Introduction: Getting Started

Data science is a field of science that aims at discovering patterns and extracting knowledge through analysis of data and developing methods to support such investigation. The field is rooted in mathematics, statistics, computer science, and vision science and has contributed to a wide array of disciplines, e.g., biology, chemistry, economics, literary studies, medicine, physical sciences, and psychology.

Game of the Name

What does data science look like? Here is a short list of some examples, followed by a discipline that appears most relevant to the problem.

  • Tracking places where crimes occur in cities for crime prevention (criminology)
  • Tracking social media postings to understand changes in public opinion (political science)
  • Dynamically changing advertisements in search engines based on browsing history and query terms (marketing)
  • Predicting trajectories of hurricanes (physical sciences)
  • Finding genetic factors contributing diseases (medicine)
  • Differentiating among novelists based on their writing styles (literary studies)
  • Winnowing an enormous candidate list of chemicals for a target effect based on their known properties (chemistry)
  • Diagnosing pulmonary diseases based on patient X ray images (medicine)
  • Identifying students that are at-risk (education)

The prominence of data science comes from the fact that the means for collecting, sharing and analyzing data have become widely accessible thanks to the rise of computers. In many disciplines, research by way of data science has received a formidable status. It is thus important for new generations of professionals (educators, scientists, engineers, doctors, etc.) to understand data science fundamentals and know how to start explorations using data science. The objective of this text is to introduce the basics of data science and to teach data science tools and concepts that have immediate practical value to the students’ field of interest.

One such tool that we will study is the programming language R. R has its roots in statistics and has a wide variety of tools that make it easy for R programmers to conduct statistical analysis and visualization. While R is certainly not the only programming language data scientists use – you may have heard about Python or Julia – we identify some key reasons for designating it as the language for this textbook.

  • The syntax (i.e., the rules for writing code in a programming language) is easier to digest and understand for newcomers to programming.
  • R is not just a language, but an interactive environment for doing data science. This makes R much more flexible than many other programming languages, and helps focus on specific parts of the data science process.
  • R allows the use of “notebooks” that allow programmers to interleave code with prose in an intuitive manner. This is a great way for data scientists to explain and share their work with peers.

After completing the text, students will be able to keep running and modifying their notebooks with new data sources and ideas.

Package Installation

The bare-bones version of R, sometimes called base R, is complete but requires a bit more effort to write code for data analysis. People have developed code in R for serving certain purposes and have shared it as packages. Using packages is key to successful application of R; you can load a package someone else has written into your R programming environment and use it for your coding.

A nonprofit organization promoting R, CRAN (the comprehensive R archive network), maintains packages researchers have developed. The majority of the packages we will be studying in this text are part of the tidyverse, which is actually a collection of packages that are useful for data analysis and visualization; they are designed to work together with ease.

The tidyverse can be installed with just a single line of code.

install.packages("tidyverse")

Type the above in the console, and press “Enter” to run it. R will download the packages from CRAN and install them on to your computer.

Sharing code through CRAN is the best way to make your package discoverable by the R community and give your package a “stamp of authenticity.” However, publishing to CRAN can be a frustrating (and sometimes long) process. To make package development easier, authors can first release their R package as a GitHub repository. Users can then download and install the package to their system using a package called devtools.

Many of the book’s datasets are made available through a package called edsdata which, at the time of this writing, is available only as a GitHub repository. The package can be installed using devtools. First, make sure you have devtools installed.

install.packages("devtools")

The edsdata package can then be installed using devtools as follows:

devtools::install_github("jerrybonnell/edsdata")

We will see examples that use the edsdata package later in the text. For now, let us see an example of how to plot some data using code from the tidyverse.

The world’s telephones

Base R ships with a number of off-the-shelf data sets you can play with. One of them is WordPhones, which provides the number of telephones in some large geographical regions of the world in 1951 and 1956-1961.

The analysis begins by loading the package into your programming environment.

library(tidyverse)

This dataset is a 7x7 table of numbers where the rows correspond to years and the columns correspond to seven geographical regions: North America, Europe, Asia, South America, Oceania, Africa, and Middle America (meaning Central America).

We can inspect the table contents by typing its name into the console.

WorldPhones

Run your eye down the table and observe that the number of telephones in each region increases, some by much more than others.

Suppose our goal is to plot the trend in the seven regions over the years. To accomplish this, we need to do some data tidying. Namely, we need the region and the number of telephones to appear as column pairs; we also give the year its own column.

transformed <- WorldPhones |>
  as_tibble() |>
  rownames_to_column("Year") |> 
  pivot_longer(cols = 2:8, names_to = "Region", values_to = "Count")

Here is how the new dataset looks like. We see that there are seven rows for each year and the regions and their counts appear vertically as a pair of columns.

transformed

Don’t worry if the code above seems overwhelming. We will go over each piece in great detail in this text. For now, just pay attention to what the dataset looks like after the transformation, and how it differs from the original.

We can now plot the number of telephones with the year as the horizontal axis and the count as the vertical axis. We assign a different color to each of the seven regions.

ggplot(transformed, aes(x = Year, y = Count)) +
  geom_point(aes(color = Region))

We call this a scatter plot, which we will see later in the text. This scatter plot tells us that the numbers steadily increased in North America, Europe, and Asia.

We can also plot the changes as bars where color denotes a certain region.

ggplot(transformed) +
  geom_bar(aes(x = Year, y = Count, fill = as.factor(Region)),
           stat = "identity", position = "fill") +
  labs(fill = "Region")

We call this one a stacked bar chart, which we will also see later. Every plot tells a different story. This one signals how the proportion of telephones changes across each region. For instance, the stacked bar chart makes it easier to see how the Asia and Africa regions gradually increase its share of telephone usage when compared to the scatter plot.

Can you spot some other differences between the two plots, especially in regards to what the visualizations say about the data?

Processing Text

Here is another example where we play with a textual dataset. As before, do not pay attention to the details of the code and what it is doing. Rather, familiarize yourself with the output of each code “block” and observe how it builds up toward accomplishing the goal.

The classics: Herman Melville’s Moby Dick

The Gutenberg Project is an international project to provide literary texts in a variety of formats for public use. One of the main literary works the site offers is “Moby Dick” by Herman Melville. You can download from the website by providing its link.

As before, we need tidyverse. We will also use another package called readtext.

library(tidyverse)
library(readtext)

We load the data from the Gutenberg Project and remove any preface or introductory material; we designate the loaded text with the name moby, so that we can refer to it again later on.

url <- "https://www.gutenberg.org/files/2701/2701-0.txt"
moby <- readtext(url) |>
  str_sub(27780)

The current version of the text is what data scientists call “dirty.” To make it tidy, we trim whitespaces and newline characters from the text, and lowercase all characters.

moby_chapters <- unlist(str_split(moby, fixed("CHAPTER"))) |>
  str_trim() |>
  str_replace_all("\\s+", " ") |>
  str_to_lower()

We store the text in a table called moby_df.

moby_df <- tibble("chapters" = moby_chapters) |> 
  slice(-1)

Here are what the first five chapters of Moby Dick look like after tidying.

slice_head(moby_df, n = 5)
chapters
  1. loomings. call me ishmael. some years ago—never mind how long precisely—having little or no money in my purse, and nothing particular to interest me on shore, i thought i would sail about a little
  1. the carpet-bag. i stuffed a shirt or two into my old carpet-bag, tucked it under my arm, and started for cape horn and the pacific. quitting the good city of old manhatto, i duly arrived in new bed
  1. the spouter-inn. entering that gable-ended spouter-inn, you found yourself in a wide, low, straggling entry with old-fashioned wainscots, reminding one of the bulwarks of some condemned old craft.
  1. the counterpane. upon waking next morning about daylight, i found queequeg’s arm thrown over me in the most loving and affectionate manner. you had almost thought i had been his wife. the counterpa
  1. breakfast. i quickly followed suit, and descending into the bar-room accosted the grinning landlord very pleasantly. i cherished no malice towards him, though he had been skylarking with me not a l

Plotting word relationships

Now that we have the main text stored in tabular form, we are ready to do some analysis. Let us look at some associations between words in the text, for instance, between “ship” and “sea”, and between “god” and “sea”.

We compute in each chapter how many times each of the words occur: “ship”, “sea”, and “god”. The results are stored as new columns appended to the table moby_df.

moby_df <- moby_df |>
  mutate(
    chapter_num = row_number(),
    ship = str_count(chapters, "ship"),
    sea = str_count(chapters, "sea"),
    god = str_count(chapters, "god")
  ) 

Here is what those new columns look like.

moby_df |>
  select(chapter_num, ship, sea, god)

We draw a scatter plot showing the relationships between the pairs “ship” and “sea”, and “god” and “sea”. The former is shown in cyan and the latter in red.

ggplot(moby_df) +
  geom_point(aes(x = sea, y = ship, color = "ship")) + 
  geom_point(aes(x = sea, y = god, color = "god")) + 
  ylab("count")

We see a strong association between “sea” and “ship” since chapters that mention the word “sea” a lot tend to also mention “ship” a whole lot as well. The relationship between “sea” and “god” is less apparent. There is one chapter where “god” and “sea” both occur frequently, but overall it seems that the occurrences of “god” have nothing to do with occurrences of “sea”.

Indeed, word counts can only take us so far. But they are a first step in the interpretative process. For instance, why does it seem that there is no relationship between the sea, where most of the action takes place, and religion, as exemplified by the occurrences of the word “god”? Machine-assisted analysis of texts in this manner, which extends well beyond word counts, has become so popular that an interdisciplinary field called Digital Humanities has become dedicated to its study.

A rough outline

Our two introductory examples have hopefully shown you a glimpse of what data science work looks like. Here is an outline of what you will learn in this course:

  • We begin with a coverage of the fundamentals of R programming.
  • We will move on to learning how the tidyverse can be used for data tidying and visualization.
  • We then study how to extract insights from our data using statistical inferencing technioques.
  • We end with generating models from data. We then use these to make predictions about possible outcomes for “unknown” observations using regression and text analysis techniques.

I hope that you will find the journey interesting.

Installation

To watch videos about Installing R and RStudio, go to the Further Information section below.

Here are the steps

  • Go to CRAN (Comprehensive R Archive Network) to install R. Choose the appropriate download (likely either Mac or PC). If you have a Mac, you should then choose the latest release that ends in .pkg. If you have a PC, you should click on base. Once it downloads, you will need to click on the file that was downloaded in order to install it. You can click through the prompts during installation. Once finished, it should tell you that it was installed successfully. (If you have a Mac, you should also download and install XQuartz here.)

  • Download RStudio from their website. You want the free RStudio Desktop version. Choose the one that matches your operating system (one will likely be suggested to you at the top of the page). Follow the prompts. On a Mac, be sure to drop RStudio into the applications folder at the end of the download. If you have downloaded it before, it will ask if you want to use the newer version. Choose yes.

Course Downloads

Here you can download some files that will be useful during the course. The most important thing to remember is to keep track of where you are downloading files to. Avoid simply using the default Downloads folder - instead, I recommend an organised Folder system:

Folder system

A really easy way to get confused very quickly when dealing with data (in fact any kind of file) is to have badly organised filing and folders. I recommend the following Folder structure for you to download and save. Do NOT save this in your Downloads folder, but somewhere separate such as your Desktop or Documents. For Windows users, avoid putting the Folder in OneDrive as that can lead to some problems later (see Problems installing packages).

Once you unzip the file, you should see folders for:

  • data

  • figures

  • prob_sets

  • r_docs

As well as:

  • iss_data_science.Rproj

Which is a project link that sets the working directory of your R session to that folder structure.

As we progress through the course, you will be able to download R code and data etc from Moodle or elsewhere, and put it into these folders.

Weekly reflections

The first r code for you to download is necessary for your homework each week: a document of notes for reflecting on what you learned in class. Save this is in your r_docs folder:

Templates

These templates will be useful whenever you want to try out R code using a simple R script or RMarkdown file. A good place for them is the r_docs folder too:

Problem sets

During the course, sometimes your homework will be problem sets. You can download them here and put them into your prob_sets folder :

Example projects (Optional)

Here you can download example project files from ISS students. If you just want to see the output in html form, go to the Resources section on Moodle.

Setting up for success

These are some steps you should take to set yourself up for an easier time using R and RStudio.

  • Create a folder on your desktop, in your Documents folder, or some other reasonable location on your computer. This should NOT be in your downloads. Let me say that again, more loudly, THIS SHOULD NOT BE IN YOUR DOWNLOADS. I recommend you use the Folder structure outlined above, and avoid using OneDrive if you are a Windows user.

  • Save new R scripts and RMarkdown files to the course folder. you created, NOT to your downloads. The best to save them place is the r_docs folder. And save often! This is not like Google docs. It will not, in general, auto save for you.

  • When you download resources from Moodle, save them to the course folder as well: csv files etc to the data folder, and R scripts and RMarkdown files to the r_docs folder. On most computers, downloaded files will be saved to your downloads. You can either change the settings or be sure to save files somewhere else after downloading. If you use a Mac, do not use Safari when downloading R markdown files from Moodle. Use some other browser (Chrome, Mozilla, etc.). Safari will add a .txt extension to the .rmd file and makes it difficult for you to fix it.

  • Change global settings! Go to Tools –> Global options. On the General tab, next to Save workspace to .RData on exit, choose Never and uncheck the box next to Restore .Rdata into workspace at startup. You can also go to the Appearance tab to customize the look of RStudio.

Check out this video which explains this point, and also shows you how to knit your first RMarkdown document.

  • Spell check. There is a spell check button (ABC with a check mark underneath it). You should use that for your assignments. In this newest version of RStudio there is also inline spellcheck so words it does not recognize will have a squiggly line under them.

  • Don’t be afraid to use the internet to search for answers to your questions. I do this all the time. And when I say all the time, I mean every single time I use R. A good place to start are using the links I put on Moodle:

    • Rseek A customised search engine which will return only content related to R

    • Qiita A popular site for asking coding questions in Japanese

Tour of RStudio

Watch the video below for a tour of RStudio. Most of what is covered in the video is also written out in the details of this section.

There are four main panes in RStudio. I will discuss all four. If you ever want to change the layout, you can do that by clicking the down arrow in the menu at the top of RStudio that looks like a window with four panes. And, if you ever lose one or more of the panes, click that same down arrow and choose Show All Panes.

Source

The main pane in the top left has the file you are working from. In this class, we will work with R Markdown files, .rmd files for short. I talk about those more below.

Console

The console in the lower left is where the code is evaluated. Since we can also see the code evaluated within the .rmd file, I often keep the console minimized. I will sometimes do some quick math in the console. The > is the prompt, indicating where you should start your code.

When you knit (compile) your document, this pane will show the complication process in a tab called R Markdown. If you get an error, you will see it there.

Environment, History, Connections, Tutorial

The pane in the upper right has a few tabs of interest. The Environment tab shows anything that has been saved to the workspace. So, if you read in a dataset or create a new named dataset, variable, etc., it will show up there. You can do some basic exploration of those items by clicking on them in the Environment.

The History tab shows your history of code that has been run in this session. It is sometimes helpful if you want to get to an old piece of code that you deleted from your .rmd file.

The Tutorials tab is new. I would encourage you to explore the resources available there.

Files, Plots, Packages, Help, Viewer

I think the most important two tabs in the lower right are Files and Help. In the Files tab, you can navigate to various locations on your computer. By default, it will be in the folder where the file you have open is located.

The Help tab is where you can go to search for help with R functions. You can type in a function name and go to that function’s help page.

Further information

The following videos should help with some aspects of the setting up and troubleshooting:

Installing R and RStudio on Windows

Installing R and RStudio on a Mac

Installing packages and handling installation errors (Windows)

This video explains how to install packages to RStudio, and how to handle one of the common problems when installing:

  • not being able to install packages because the disc is not writeable.

Problems installing packages

Unfortunately, people sometimes have problems installing packages on Windows 10. Two of the main issues are:

  1. not being able to install packages because the disc is not writeable.

  2. packages saving to OneDrive automatically

The video above briefly explained how to deal with the first problem, in summary:

  • quit RStudio

  • right-click on RStudio icon

  • choose Run as Administrator (管理者として実行)

The second problem is a bit more complicated, but this page has detailed instructions on dealing with it.

For more details about handling installation problems (in Japanese), see this excellent blog post.

Setting Up a Workflow

RStudio is an integrated development environment (also known as an IDE) popularly used among data scientists for writing R code. It is a powerful tool that can be used to write and debug code, view visualizations, pull up documentation, write “notebooks”, and much more which we will probably not get to see! In this section we will go over setting up RStudio on your machine.

Posit Cloud and RStudio

There are two ways to work with R. The first option is Posit Cloud, a lightweight and cloud-based interface to RStudio. If you use Posit Cloud, you can code right from your favorite browser! However, because Posit Cloud is cloud-based, the code you write is not executed on your machine and, instead, uses someone else’s computational resources. Posit Cloud offers a “free tier” that gives access to limited resources (1GB memory and 1 CPU per project) with 25 project hours/month. This should be sufficient for the examples and exercises covered in this text, but you may run up against the project hour quota. A paid tier is available that gives more project hours and computational power. We recommend Posit Cloud to students with older machines and anyone who prefers a zero-installation setup for getting started. Posit Cloud is available here:

The second option is to install R and RStudio Desktop directly to your system. They can be found at the following links:

Creating a RStudio Project

If you are working on Posit Cloud, navigate to your workspace and create a new RStudio project by clicking “New Project” and then “New RStudio Project”. This should bring you into a RStudio environment. Once there, feel free to skip to the next section.

If you are working with a local installation, launch the RStudio application. There may be some “getting started” help guides that you are presented with, which you can ignore for now. Your next step will be to create a R project by going to: File > New Project....

## here() starts at /Users/timmarchand/Desktop/CLIL_data_science_1

From the options that are presented, select New Directory > New Project. This should bring up the following screen.

In the input box that asks for a “Directory name”, you can name it however you like. For instance, we named ours “CSC100”. The default directory for this project is fine, but do make a note of it; also, do not worry about any of the check boxes and leave those unchecked.

When you are ready, go ahead and select Create Project.

Meet RStudio

You should now be presented with a view that looks like the following:

Let us go over each of the labeled parts.

  • Console. This is a great place to get started coding in R! It isn’t fully featured like a R markdown notebook is (which we will see in a moment) and you wouldn’t want to put anything important here as it will be lost as soon as you exit RStudio. However, it can be useful for checking small things, e.g. as a built-in calculator. Try out 2 + 2 and see what you get! You can also check the current “working directory” by typing getwd(). This will pull up the directory/folder on your machine where you created this project.

  • Environment. This is where RStudio keeps track of “objects” that R has created during your session. We haven’t learned what these are yet, but you can revisit this part of the notes again to make sense of what is going on here. To demonstrate this, let us create an object my_value that holds the value 5. The benefit of the environment view is that it reminds us of the current value held by the object. Run this cell in the “Console” area of RStudio and then glance over at the “Environment” view.

my_value <- 5

Note what happens in the environment view if we were to change the value. As before, copy the following line of code into your console.

my_value <- "hello data science!"
  • File Explorer/Plots/Help. This area is actually a “three-in-one”. At the moment, it presents you the files and folders that currently exist inside your project – which is practically nothing at the moment. We will create some directories in just a moment.

The plots view reveals itself when you have created a visualization on the console. Here is an example. You need not understand what this code does; simply copy and paste into the console, and run.

plot(cyl ~ mpg, mtcars)

Let us navigate to the help tab, which should be one or two tabs down from the “Plots” tab. Here, we can look up documentation about functions or datasets we would like to learn more about. For instance, in the search bar, we can type plot to look up information for the function plot we just used earlier.

An equivalent, and perhaps more straightforward, way of looking up documentation is right from the console. Just type in ?plot, and hit enter.

Organizing your work

We can create folders in our project to better organize our work. We recommend the following structure. You can use the New Folder button in the file explorer view to create these directories.

This folder structure can be useful if you are taking a course that requires using RStudio. The folder names should be self-explanatory, but here is a brief explanation:

  • labs, for working on lab assignments.
  • hw, for working on homework assignments.
  • notes, for your own notes.
  • project, for working on projects.

R markdown notebooks

R markdown notebooks allow users to intersperse code with prose in an intuitive manner. This is great to use in practice for sharing and communicating your work to peers.

We can try playing with an example notebook that RStudio automatically generates when creating a notebook. Let us try it.

Navigate to File > New File > R Notebook. Save this notebook somewhere appropriate, say, in your notes directory. Here is what you should be seeing:

Let us go over the parts.

  • Markdown. Here you can type text as you would normally in text processing software like Notepad++, TextEdit, or Word. The cool feature is that the text can be marked up using a language called markdown. Here is a cheat sheet that you can use as reference.

  • Code. Here is where we will be writing most of our R code. We may also call these code “cells” or “blocks”. When you are ready to run a code block, you can press the green “play” button that appears toward the top right of the block. Observe how it produces output in-line just below the code – neat, right?

  • Option Pane. There are some features here you may wish to explore like the Run button which allows you to run all the code blocks in a notebook at once, etc. The feature we would like to draw your attention to is something called knitting, which can be found after pressing the downward arrow next to Preview. This should show several options, one of which is Knit to PDF. Go ahead and select it.

If you navigate to the notes directory in the File Explorer (or wherever you created this notebook), you should see a PDF file that has been generated. Clicking on it in the File Explorer should present you with a PDF version of the notebook.

What RStudio did was take our R markdown file and convert it to a PDF using LaTeX. Beneath each code block is the corresponding output, interspersed neatly with the surrounding prose – all formatting taken care of for you :-)

Preferences settings

Before we end this tutorial, we also need to set two RStudio settings. This will help to avoid any heartache when working through this text.

Open up Preferences in RStudio. Do the following in the General tab:

  • Uncheck the box that says “Restore .RData into workspace at startup”
  • Following the text that says “Save workspace data to .RData on exit:”, select Never.

This completes the setup!

Exercises

Be sure to install and load the following packages into your R environment before beginning this exercise set.

library(tidyverse)
library(edsdata)
library(gapminder)
library(emojifont)

Question 1 The goal of this question is to develop familiarity with R, RStudio, and installing/loading packages into a RStudio environment. All work for this question can be done using the Console window inside RStudio or, preferably, by creating code chunks inside a R markdown notebook (see Section 1.4).

  • Question 1.1 Install the packages tidyverse, emojifont, devtools, and edsdata on your system. Recall that the edsdata package is not available on CRAN and must be installed using install_github from the devtools package. Then load these packages into your environment.

  • Question 1.2 emoji() is a function from the package emojifont which converts an emoji alias to its “unicode” representation. The following expression gives an example. Type and run the following code chunk:

    emoji("star")

    Try converting another emoji alias name to its “unicode” representation.

  • Question 1.3 There are actually a lot of emojis with stars. Use the function search_emoji() to find all aliases for “star”. How many are there? Hint: use ?search_emoji to pull up the help documentation for this function. That is always a good idea when you are in doubt of how to use a function.

  • Question 1.4 We have made a coding blunder in the next chunk. Type the following and run this code chunk to see what happens. Then fix the code so that you can run the chunk without error and see the intended message.

    print("what is missing?
  • Question 1.5 What happens if we try printing a name that has not been assigned anything? Try to display the value for the name bubble or tea. What message is produced? Are you surprised?

    bubble
    tea

Question 2 We saw in the textbook that we can visualize word relationships in Moby Dick using tidyverse and the R programming language. In this part we will continue exploring these relationships and answer some questions about what is being represented. Be sure you have also read Section 1.3 of the textbook.

Run the following chunk to produce the visualization we will examine for this question. You do NOT need to understand what is happening in the following code!

library(edsdata)
ggplot(moby_dick_counts) + 
  geom_point(aes(x = whale, y = sea, color = "sea")) + 
  geom_point(aes(x = whale, y = ahab, color = "ahab")) + 
  ylab("count")
  • Question 2.1 What is being represented by this visualization? What is shown on the x-axis? On the y-axis? Please explain your answer.

  • Question 2.2 About how many times did the word “whale” occur in the chapter that contained the most number of occurrences of the word “ahab”? Assign either 1, 2, 3, 4, or 5 to the name moby_q2 below.

      1. 20
      2. 30
      3. 35
      4. 55
      5. 60
  • Question 2.3 It seems that the occurrences of “whale” are not as closely associated with “ahab” as it is with “sea”. Is this a fair observation? Explain why or why not.

Question 3 According to the textbook, which of the following, if any, are data science tasks? Explain why or why not.

  • An intern examines performance at a company by computing mean and median quarterly earnings using spreadsheet software (e.g., Microsoft Excel, Numbers, etc).
  • A learning management system (LMS) collects large volumes of data on user activity patterns, module interactions, and diagnostics.
  • A research cohort explores issues of authorship in a collection of classic English works by using various text analysis tools (e.g., frequency analysis, sentiment analysis, etc).
  • A colleague reports results from a statistical analysis on an Alzheimer’s disease study using line charts, “box-and-whisker” plots, and histograms.

Question 4 The textbook lists some examples of what work in data science looks like. Can you come up with two or three additional examples of data science? Why do your examples fall within the boundaries of “data science”, as defined by the textbook?

Question 5 Following are steps in a data science workflow that are out-of-order.

  1. collecting data
  2. communicating the results to the management
  3. assembling the results into a report
  4. transforming the data to determine the method for analysis
  5. determining the data sources
  6. “tidying” the data, including filling in missing values
  7. performing the analysis
  • Question 5.1 Put the above steps in the correct order.

  • Question 5.2 Data science work is often an iterative and cyclical process that repeats until enough insight can be gleaned from the data. From the workflow outlined in Question 5.1, explain which of the steps may be repeated multiple times.

LS0tCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDoKICAgIGNzczogbGFiLmNzcwogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA1CiAgICB0b2NfZmxvYXQ6IHllcwotLS0KClxtYWlubWF0dGVyCgoKIyBJbnRyb2R1Y3Rpb246IEdldHRpbmcgU3RhcnRlZCB7LX0KCmBgYHtyIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkod2Vic2hvdCkKb3B0aW9ucyh0aW55dGV4LmNsZWFuID0gRkFMU0UpCmBgYAoKRGF0YSBzY2llbmNlIGlzIGEgZmllbGQgb2Ygc2NpZW5jZSB0aGF0IGFpbXMgYXQgZGlzY292ZXJpbmcgcGF0dGVybnMgYW5kIGV4dHJhY3Rpbmcga25vd2xlZGdlIHRocm91Z2ggYW5hbHlzaXMgb2YgZGF0YSBhbmQgZGV2ZWxvcGluZyBtZXRob2RzIHRvIHN1cHBvcnQgc3VjaCBpbnZlc3RpZ2F0aW9uLiBUaGUgZmllbGQgaXMgcm9vdGVkIGluIG1hdGhlbWF0aWNzLCBzdGF0aXN0aWNzLCBjb21wdXRlciBzY2llbmNlLCBhbmQgdmlzaW9uIHNjaWVuY2UgYW5kIGhhcyBjb250cmlidXRlZCB0byBhIHdpZGUgYXJyYXkgb2YgZGlzY2lwbGluZXMsIGUuZy4sICBiaW9sb2d5LCBjaGVtaXN0cnksIGVjb25vbWljcywgbGl0ZXJhcnkgc3R1ZGllcywgbWVkaWNpbmUsIHBoeXNpY2FsIHNjaWVuY2VzLCBhbmQgcHN5Y2hvbG9neS4gCgoKIyMgR2FtZSBvZiB0aGUgTmFtZSB7LX0KCldoYXQgZG9lcyBkYXRhIHNjaWVuY2UgbG9vayBsaWtlPyBIZXJlIGlzIGEgc2hvcnQgbGlzdCBvZiBzb21lIGV4YW1wbGVzLCBmb2xsb3dlZCBieSBhIGRpc2NpcGxpbmUgdGhhdCBhcHBlYXJzIG1vc3QgcmVsZXZhbnQgdG8gdGhlIHByb2JsZW0uIAoKKiBUcmFja2luZyBwbGFjZXMgd2hlcmUgY3JpbWVzIG9jY3VyIGluIGNpdGllcyBmb3IgY3JpbWUgcHJldmVudGlvbiAoY3JpbWlub2xvZ3kpCiogVHJhY2tpbmcgc29jaWFsIG1lZGlhIHBvc3RpbmdzIHRvIHVuZGVyc3RhbmQgY2hhbmdlcyBpbiBwdWJsaWMgb3BpbmlvbiAocG9saXRpY2FsIHNjaWVuY2UpCiogRHluYW1pY2FsbHkgY2hhbmdpbmcgYWR2ZXJ0aXNlbWVudHMgaW4gc2VhcmNoIGVuZ2luZXMgYmFzZWQgb24gYnJvd3NpbmcgaGlzdG9yeSBhbmQgcXVlcnkgdGVybXMgKG1hcmtldGluZykKKiBQcmVkaWN0aW5nIHRyYWplY3RvcmllcyBvZiBodXJyaWNhbmVzIChwaHlzaWNhbCBzY2llbmNlcykKKiBGaW5kaW5nIGdlbmV0aWMgZmFjdG9ycyBjb250cmlidXRpbmcgZGlzZWFzZXMgKG1lZGljaW5lKQoqIERpZmZlcmVudGlhdGluZyBhbW9uZyBub3ZlbGlzdHMgYmFzZWQgb24gdGhlaXIgd3JpdGluZyBzdHlsZXMgKGxpdGVyYXJ5IHN0dWRpZXMpCiogV2lubm93aW5nIGFuIGVub3Jtb3VzIGNhbmRpZGF0ZSBsaXN0IG9mIGNoZW1pY2FscyBmb3IgYSB0YXJnZXQgZWZmZWN0IGJhc2VkIG9uIHRoZWlyIGtub3duIHByb3BlcnRpZXMgKGNoZW1pc3RyeSkKKiBEaWFnbm9zaW5nIHB1bG1vbmFyeSBkaXNlYXNlcyBiYXNlZCBvbiBwYXRpZW50IFggcmF5IGltYWdlcyAobWVkaWNpbmUpCiogSWRlbnRpZnlpbmcgc3R1ZGVudHMgdGhhdCBhcmUgYXQtcmlzayAoZWR1Y2F0aW9uKQoKVGhlIHByb21pbmVuY2Ugb2YgZGF0YSBzY2llbmNlIGNvbWVzIGZyb20gdGhlIGZhY3QgdGhhdCB0aGUgbWVhbnMgZm9yIGNvbGxlY3RpbmcsIHNoYXJpbmcgYW5kIGFuYWx5emluZyBkYXRhIGhhdmUgYmVjb21lIHdpZGVseSBhY2Nlc3NpYmxlIHRoYW5rcyB0byB0aGUgcmlzZSBvZiBjb21wdXRlcnMuIEluIG1hbnkgZGlzY2lwbGluZXMsIHJlc2VhcmNoIGJ5IHdheSBvZiBkYXRhIHNjaWVuY2UgaGFzIHJlY2VpdmVkIGEgZm9ybWlkYWJsZSBzdGF0dXMuIEl0IGlzIHRodXMgaW1wb3J0YW50IGZvciBuZXcgZ2VuZXJhdGlvbnMgb2YgcHJvZmVzc2lvbmFscyAoZWR1Y2F0b3JzLCBzY2llbnRpc3RzLCBlbmdpbmVlcnMsIGRvY3RvcnMsIGV0Yy4pIHRvIHVuZGVyc3RhbmQgZGF0YSBzY2llbmNlIGZ1bmRhbWVudGFscyBhbmQga25vdyBob3cgdG8gc3RhcnQgZXhwbG9yYXRpb25zIHVzaW5nIGRhdGEgc2NpZW5jZS4gVGhlIG9iamVjdGl2ZSBvZiB0aGlzIHRleHQgaXMgdG8gaW50cm9kdWNlIHRoZSBiYXNpY3Mgb2YgZGF0YSBzY2llbmNlIGFuZCB0byB0ZWFjaCBkYXRhIHNjaWVuY2UgdG9vbHMgYW5kIGNvbmNlcHRzIHRoYXQgaGF2ZSBpbW1lZGlhdGUgcHJhY3RpY2FsIHZhbHVlIHRvIHRoZSBzdHVkZW50cycgZmllbGQgb2YgaW50ZXJlc3QuICAKCk9uZSBzdWNoIHRvb2wgdGhhdCB3ZSB3aWxsIHN0dWR5IGlzIHRoZSBwcm9ncmFtbWluZyBsYW5ndWFnZSBSLiBSIGhhcyBpdHMgcm9vdHMgaW4gc3RhdGlzdGljcyBhbmQgaGFzIGEgd2lkZSB2YXJpZXR5IG9mIHRvb2xzIHRoYXQgbWFrZSBpdCBlYXN5IGZvciBSIHByb2dyYW1tZXJzIHRvIGNvbmR1Y3Qgc3RhdGlzdGljYWwgYW5hbHlzaXMgYW5kIHZpc3VhbGl6YXRpb24uIFdoaWxlIFIgaXMgY2VydGFpbmx5IG5vdCB0aGUgb25seSBwcm9ncmFtbWluZyBsYW5ndWFnZSBkYXRhIHNjaWVudGlzdHMgdXNlIC0tIHlvdSBtYXkgaGF2ZSBoZWFyZCBhYm91dCBQeXRob24gb3IgSnVsaWEgLS0gd2UgaWRlbnRpZnkgc29tZSBrZXkgcmVhc29ucyBmb3IgZGVzaWduYXRpbmcgaXQgYXMgdGhlIGxhbmd1YWdlIGZvciB0aGlzIHRleHRib29rLiAKCiogVGhlIHN5bnRheCAoaS5lLiwgdGhlIHJ1bGVzIGZvciB3cml0aW5nIGNvZGUgaW4gYSBwcm9ncmFtbWluZyBsYW5ndWFnZSkgaXMgZWFzaWVyIHRvIGRpZ2VzdCBhbmQgdW5kZXJzdGFuZCBmb3IgbmV3Y29tZXJzIHRvIHByb2dyYW1taW5nLiAKKiBSIGlzIG5vdCBqdXN0IGEgbGFuZ3VhZ2UsIGJ1dCBhbiBpbnRlcmFjdGl2ZSBlbnZpcm9ubWVudCBmb3IgZG9pbmcgZGF0YSBzY2llbmNlLiBUaGlzIG1ha2VzIFIgbXVjaCBtb3JlIGZsZXhpYmxlIHRoYW4gbWFueSBvdGhlciBwcm9ncmFtbWluZyBsYW5ndWFnZXMsIGFuZCBoZWxwcyBmb2N1cyBvbiBzcGVjaWZpYyBwYXJ0cyBvZiB0aGUgZGF0YSBzY2llbmNlIHByb2Nlc3MuIAoqIFIgYWxsb3dzIHRoZSB1c2Ugb2YgIm5vdGVib29rcyIgdGhhdCBhbGxvdyBwcm9ncmFtbWVycyB0byBpbnRlcmxlYXZlIGNvZGUgd2l0aCBwcm9zZSBpbiBhbiBpbnR1aXRpdmUgbWFubmVyLiBUaGlzIGlzIGEgZ3JlYXQgd2F5IGZvciBkYXRhIHNjaWVudGlzdHMgdG8gZXhwbGFpbiBhbmQgc2hhcmUgdGhlaXIgd29yayB3aXRoIHBlZXJzLiAKCkFmdGVyIGNvbXBsZXRpbmcgdGhlIHRleHQsIHN0dWRlbnRzIHdpbGwgYmUgYWJsZSB0byBrZWVwIHJ1bm5pbmcgYW5kIG1vZGlmeWluZyB0aGVpciBub3RlYm9va3Mgd2l0aCBuZXcgZGF0YSBzb3VyY2VzIGFuZCBpZGVhcy4KCiMjIFBhY2thZ2UgSW5zdGFsbGF0aW9uIHstfQoKVGhlIGJhcmUtYm9uZXMgdmVyc2lvbiBvZiBSLCBzb21ldGltZXMgY2FsbGVkICpiYXNlKiBSLCBpcyBjb21wbGV0ZSBidXQgcmVxdWlyZXMgYSBiaXQgbW9yZSBlZmZvcnQgdG8gd3JpdGUgY29kZSBmb3IgZGF0YSBhbmFseXNpcy4gUGVvcGxlIGhhdmUgZGV2ZWxvcGVkIGNvZGUgaW4gUiBmb3Igc2VydmluZyBjZXJ0YWluIHB1cnBvc2VzIGFuZCBoYXZlIHNoYXJlZCBpdCBhcyAqcGFja2FnZXMqLiBVc2luZyBwYWNrYWdlcyBpcyBrZXkgdG8gc3VjY2Vzc2Z1bCBhcHBsaWNhdGlvbiBvZiBSOyB5b3UgY2FuIGxvYWQgYSBwYWNrYWdlIHNvbWVvbmUgZWxzZSBoYXMgd3JpdHRlbiBpbnRvIHlvdXIgUiBwcm9ncmFtbWluZyBlbnZpcm9ubWVudCBhbmQgdXNlIGl0IGZvciB5b3VyIGNvZGluZy4KCkEgbm9ucHJvZml0IG9yZ2FuaXphdGlvbiBwcm9tb3RpbmcgUiwgW0NSQU5dKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnLykgKHRoZSAqKmMqKm9tcHJlaGVuc2l2ZSAqKlIqKiAqKmEqKnJjaGl2ZSAqKm4qKmV0d29yayksIG1haW50YWlucyBwYWNrYWdlcyByZXNlYXJjaGVycyBoYXZlIGRldmVsb3BlZC4gVGhlIG1ham9yaXR5IG9mIHRoZSBwYWNrYWdlcyB3ZSB3aWxsIGJlIHN0dWR5aW5nIGluIHRoaXMgdGV4dCBhcmUgcGFydCBvZiB0aGUgKnRpZHl2ZXJzZSosIHdoaWNoIGlzIGFjdHVhbGx5IGEgY29sbGVjdGlvbiBvZiBwYWNrYWdlcyB0aGF0IGFyZSB1c2VmdWwgZm9yIGRhdGEgYW5hbHlzaXMgYW5kIHZpc3VhbGl6YXRpb247IHRoZXkgYXJlIGRlc2lnbmVkIHRvIHdvcmsgdG9nZXRoZXIgd2l0aCBlYXNlLiAgCgpUaGUgdGlkeXZlcnNlIGNhbiBiZSBpbnN0YWxsZWQgd2l0aCBqdXN0IGEgc2luZ2xlIGxpbmUgb2YgY29kZS4gCgpgYGB7ciBldmFsPUZBTFNFfQppbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQpgYGAKClR5cGUgdGhlIGFib3ZlIGluIHRoZSBjb25zb2xlLCBhbmQgcHJlc3MgIkVudGVyIiB0byBydW4gaXQuIFIgd2lsbCBkb3dubG9hZCB0aGUgcGFja2FnZXMgZnJvbSBDUkFOIGFuZCBpbnN0YWxsIHRoZW0gb24gdG8geW91ciBjb21wdXRlci4gCgpTaGFyaW5nIGNvZGUgdGhyb3VnaCBDUkFOIGlzIHRoZSBiZXN0IHdheSB0byBtYWtlIHlvdXIgcGFja2FnZSBkaXNjb3ZlcmFibGUgYnkgdGhlIFIgY29tbXVuaXR5IGFuZCBnaXZlIHlvdXIgcGFja2FnZSBhICJzdGFtcCBvZiBhdXRoZW50aWNpdHkuIiBIb3dldmVyLCBwdWJsaXNoaW5nIHRvIENSQU4gY2FuIGJlIGEgZnJ1c3RyYXRpbmcgKGFuZCBzb21ldGltZXMgbG9uZykgcHJvY2Vzcy4gVG8gbWFrZSBwYWNrYWdlIGRldmVsb3BtZW50IGVhc2llciwgYXV0aG9ycyBjYW4gZmlyc3QgcmVsZWFzZSB0aGVpciBSIHBhY2thZ2UgYXMgYSBbR2l0SHViXShodHRwczovL2dpdGh1Yi5jb20vKSByZXBvc2l0b3J5LiBVc2VycyBjYW4gdGhlbiBkb3dubG9hZCBhbmQgaW5zdGFsbCB0aGUgcGFja2FnZSB0byB0aGVpciBzeXN0ZW0gdXNpbmcgYSBwYWNrYWdlIGNhbGxlZCBgZGV2dG9vbHNgLiAKCk1hbnkgb2YgdGhlIGJvb2sncyBkYXRhc2V0cyBhcmUgbWFkZSBhdmFpbGFibGUgdGhyb3VnaCBhIHBhY2thZ2UgY2FsbGVkIGBlZHNkYXRhYCB3aGljaCwgYXQgdGhlIHRpbWUgb2YgdGhpcyB3cml0aW5nLCBpcyBhdmFpbGFibGUgb25seSBhcyBhIEdpdEh1YiByZXBvc2l0b3J5LiBUaGUgcGFja2FnZSBjYW4gYmUgaW5zdGFsbGVkIHVzaW5nIGBkZXZ0b29sc2AuIEZpcnN0LCBtYWtlIHN1cmUgeW91IGhhdmUgYGRldnRvb2xzYCBpbnN0YWxsZWQuCgpgYGB7ciBldmFsPUZBTFNFfQppbnN0YWxsLnBhY2thZ2VzKCJkZXZ0b29scyIpCmBgYAoKVGhlIGBlZHNkYXRhYCBwYWNrYWdlIGNhbiB0aGVuIGJlIGluc3RhbGxlZCB1c2luZyBgZGV2dG9vbHNgIGFzIGZvbGxvd3M6CgpgYGB7ciBldmFsPUZBTFNFfQpkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoImplcnJ5Ym9ubmVsbC9lZHNkYXRhIikKYGBgCgpXZSB3aWxsIHNlZSBleGFtcGxlcyB0aGF0IHVzZSB0aGUgYGVkc2RhdGFgIHBhY2thZ2UgbGF0ZXIgaW4gdGhlIHRleHQuIEZvciBub3csIGxldCB1cyBzZWUgYW4gZXhhbXBsZSBvZiBob3cgdG8gcGxvdCBzb21lIGRhdGEgdXNpbmcgY29kZSBmcm9tIHRoZSBgdGlkeXZlcnNlYC4gCgojIyMgVGhlIHdvcmxkJ3MgdGVsZXBob25lcyB7LX0KCkJhc2UgUiBzaGlwcyB3aXRoIGEgbnVtYmVyIG9mIG9mZi10aGUtc2hlbGYgZGF0YSBzZXRzIHlvdSBjYW4gcGxheSB3aXRoLiBPbmUgb2YgdGhlbSBpcyBgV29yZFBob25lc2AsIHdoaWNoIHByb3ZpZGVzIHRoZSBudW1iZXIgb2YgdGVsZXBob25lcyBpbiBzb21lIGxhcmdlIGdlb2dyYXBoaWNhbCByZWdpb25zIG9mIHRoZSB3b3JsZCBpbiAxOTUxIGFuZCAxOTU2LTE5NjEuCgpUaGUgYW5hbHlzaXMgYmVnaW5zIGJ5IGxvYWRpbmcgdGhlIHBhY2thZ2UgaW50byB5b3VyIHByb2dyYW1taW5nIGVudmlyb25tZW50LgoKYGBge3IgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKClRoaXMgZGF0YXNldCBpcyBhIDd4NyB0YWJsZSBvZiBudW1iZXJzIHdoZXJlIHRoZSByb3dzIGNvcnJlc3BvbmQgdG8geWVhcnMgYW5kIHRoZSBjb2x1bW5zIGNvcnJlc3BvbmQgdG8gc2V2ZW4gZ2VvZ3JhcGhpY2FsIHJlZ2lvbnM6IE5vcnRoIEFtZXJpY2EsIEV1cm9wZSwgQXNpYSwgU291dGggQW1lcmljYSwgT2NlYW5pYSwgQWZyaWNhLCBhbmQgTWlkZGxlIEFtZXJpY2EgKG1lYW5pbmcgQ2VudHJhbCBBbWVyaWNhKS4KCldlIGNhbiBpbnNwZWN0IHRoZSB0YWJsZSBjb250ZW50cyBieSB0eXBpbmcgaXRzIG5hbWUgaW50byB0aGUgY29uc29sZS4gCgpgYGB7ciBldmFsID0gRkFMU0V9CldvcmxkUGhvbmVzCmBgYAoKYGBge3IgZWNobyA9IEZBTFNFfQphc190aWJibGUoV29ybGRQaG9uZXMpCmBgYAoKUnVuIHlvdXIgZXllIGRvd24gdGhlIHRhYmxlIGFuZCBvYnNlcnZlIHRoYXQgdGhlIG51bWJlciBvZiB0ZWxlcGhvbmVzIGluIGVhY2ggcmVnaW9uIGluY3JlYXNlcywgc29tZSBieSBtdWNoIG1vcmUgdGhhbiBvdGhlcnMuICAKClN1cHBvc2Ugb3VyIGdvYWwgaXMgdG8gcGxvdCB0aGUgdHJlbmQgaW4gdGhlIHNldmVuIHJlZ2lvbnMgb3ZlciB0aGUgeWVhcnMuIFRvIGFjY29tcGxpc2ggdGhpcywgd2UgbmVlZCB0byBkbyBzb21lICpkYXRhIHRpZHlpbmcqLiBOYW1lbHksIHdlIG5lZWQgdGhlIHJlZ2lvbiBhbmQgdGhlIG51bWJlciBvZiB0ZWxlcGhvbmVzIHRvIGFwcGVhciBhcyBjb2x1bW4gcGFpcnM7IHdlIGFsc28gZ2l2ZSB0aGUgeWVhciBpdHMgb3duIGNvbHVtbi4gCgpgYGB7cn0KdHJhbnNmb3JtZWQgPC0gV29ybGRQaG9uZXMgfD4KICBhc190aWJibGUoKSB8PgogIHJvd25hbWVzX3RvX2NvbHVtbigiWWVhciIpIHw+IAogIHBpdm90X2xvbmdlcihjb2xzID0gMjo4LCBuYW1lc190byA9ICJSZWdpb24iLCB2YWx1ZXNfdG8gPSAiQ291bnQiKQpgYGAKCkhlcmUgaXMgaG93IHRoZSBuZXcgZGF0YXNldCBsb29rcyBsaWtlLiBXZSBzZWUgdGhhdCB0aGVyZSBhcmUgc2V2ZW4gcm93cyBmb3IgZWFjaCB5ZWFyIGFuZCB0aGUgcmVnaW9ucyBhbmQgdGhlaXIgY291bnRzIGFwcGVhciB2ZXJ0aWNhbGx5IGFzIGEgcGFpciBvZiBjb2x1bW5zLgoKYGBge3J9CnRyYW5zZm9ybWVkCmBgYAoKRG9uJ3Qgd29ycnkgaWYgdGhlIGNvZGUgYWJvdmUgc2VlbXMgb3ZlcndoZWxtaW5nLiBXZSB3aWxsIGdvIG92ZXIgZWFjaCBwaWVjZSBpbiBncmVhdCBkZXRhaWwgaW4gdGhpcyB0ZXh0LiBGb3Igbm93LCBqdXN0IHBheSBhdHRlbnRpb24gdG8gd2hhdCB0aGUgZGF0YXNldCBsb29rcyBsaWtlIGFmdGVyIHRoZSB0cmFuc2Zvcm1hdGlvbiwgYW5kIGhvdyBpdCBkaWZmZXJzIGZyb20gdGhlIG9yaWdpbmFsLiAKCldlIGNhbiBub3cgcGxvdCB0aGUgbnVtYmVyIG9mIHRlbGVwaG9uZXMgd2l0aCB0aGUgeWVhciBhcyB0aGUgaG9yaXpvbnRhbCBheGlzIGFuZCB0aGUgY291bnQgYXMgdGhlIHZlcnRpY2FsIGF4aXMuIFdlIGFzc2lnbiBhIGRpZmZlcmVudCBjb2xvciB0byBlYWNoIG9mIHRoZSBzZXZlbiByZWdpb25zLgoKYGBge3J9CmdncGxvdCh0cmFuc2Zvcm1lZCwgYWVzKHggPSBZZWFyLCB5ID0gQ291bnQpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBSZWdpb24pKQpgYGAKCldlIGNhbGwgdGhpcyBhICpzY2F0dGVyIHBsb3QqLCB3aGljaCB3ZSB3aWxsIHNlZSBsYXRlciBpbiB0aGUgdGV4dC4gVGhpcyBzY2F0dGVyIHBsb3QgdGVsbHMgdXMgdGhhdCB0aGUgbnVtYmVycyBzdGVhZGlseSBpbmNyZWFzZWQgaW4gTm9ydGggQW1lcmljYSwgRXVyb3BlLCBhbmQgQXNpYS4KCldlIGNhbiBhbHNvIHBsb3QgdGhlIGNoYW5nZXMgYXMgYmFycyB3aGVyZSBjb2xvciBkZW5vdGVzIGEgY2VydGFpbiByZWdpb24uCgpgYGB7cn0KZ2dwbG90KHRyYW5zZm9ybWVkKSArCiAgZ2VvbV9iYXIoYWVzKHggPSBZZWFyLCB5ID0gQ291bnQsIGZpbGwgPSBhcy5mYWN0b3IoUmVnaW9uKSksCiAgICAgICAgICAgc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImZpbGwiKSArCiAgbGFicyhmaWxsID0gIlJlZ2lvbiIpCmBgYAoKV2UgY2FsbCB0aGlzIG9uZSBhICpzdGFja2VkIGJhciBjaGFydCosIHdoaWNoIHdlIHdpbGwgYWxzbyBzZWUgbGF0ZXIuIEV2ZXJ5IHBsb3QgdGVsbHMgYSBkaWZmZXJlbnQgc3RvcnkuIFRoaXMgb25lIHNpZ25hbHMgaG93IHRoZSAqcHJvcG9ydGlvbiogb2YgdGVsZXBob25lcyBjaGFuZ2VzIGFjcm9zcyBlYWNoIHJlZ2lvbi4gRm9yIGluc3RhbmNlLCB0aGUgc3RhY2tlZCBiYXIgY2hhcnQgbWFrZXMgaXQgZWFzaWVyIHRvIHNlZSBob3cgdGhlIEFzaWEgYW5kIEFmcmljYSByZWdpb25zIGdyYWR1YWxseSBpbmNyZWFzZSBpdHMgc2hhcmUgb2YgdGVsZXBob25lIHVzYWdlIHdoZW4gY29tcGFyZWQgdG8gdGhlIHNjYXR0ZXIgcGxvdC4gICAgICAgCgpDYW4geW91IHNwb3Qgc29tZSBvdGhlciBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSB0d28gcGxvdHMsIGVzcGVjaWFsbHkgaW4gcmVnYXJkcyB0byB3aGF0IHRoZSB2aXN1YWxpemF0aW9ucyBzYXkgYWJvdXQgdGhlIGRhdGE/CgojIyBQcm9jZXNzaW5nIFRleHQgey19CgpIZXJlIGlzIGFub3RoZXIgZXhhbXBsZSB3aGVyZSB3ZSBwbGF5IHdpdGggYSB0ZXh0dWFsIGRhdGFzZXQuIEFzIGJlZm9yZSwgZG8gbm90IHBheSBhdHRlbnRpb24gdG8gdGhlIGRldGFpbHMgb2YgdGhlIGNvZGUgYW5kIHdoYXQgaXQgaXMgZG9pbmcuIFJhdGhlciwgZmFtaWxpYXJpemUgeW91cnNlbGYgd2l0aCB0aGUgb3V0cHV0IG9mIGVhY2ggY29kZSAiYmxvY2siIGFuZCBvYnNlcnZlIGhvdyBpdCBidWlsZHMgdXAgdG93YXJkIGFjY29tcGxpc2hpbmcgdGhlIGdvYWwuIAoKIyMjIFRoZSBjbGFzc2ljczogSGVybWFuIE1lbHZpbGxlJ3MgTW9ieSBEaWNrIHstfQoKW1RoZSBHdXRlbmJlcmcgUHJvamVjdF0oaHR0cDovL3d3dy5ndXRlbmJlcmcub3JnLykgaXMgYW4gaW50ZXJuYXRpb25hbCBwcm9qZWN0IHRvIHByb3ZpZGUgbGl0ZXJhcnkgdGV4dHMgaW4gYSB2YXJpZXR5IG9mIGZvcm1hdHMgZm9yIHB1YmxpYyB1c2UuIE9uZSBvZiB0aGUgbWFpbiBsaXRlcmFyeSB3b3JrcyB0aGUgc2l0ZSBvZmZlcnMgaXMgIk1vYnkgRGljayIgYnkgSGVybWFuIE1lbHZpbGxlLiBZb3UgY2FuIGRvd25sb2FkIGZyb20gdGhlIHdlYnNpdGUgYnkgcHJvdmlkaW5nIGl0cyBsaW5rLgoKQXMgYmVmb3JlLCB3ZSBuZWVkIGB0aWR5dmVyc2VgLiBXZSB3aWxsIGFsc28gdXNlIGFub3RoZXIgcGFja2FnZSBjYWxsZWQgYHJlYWR0ZXh0YC4KCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocmVhZHRleHQpCmBgYAoKV2UgbG9hZCB0aGUgZGF0YSBmcm9tIHRoZSBHdXRlbmJlcmcgUHJvamVjdCBhbmQgcmVtb3ZlIGFueSBwcmVmYWNlIG9yIGludHJvZHVjdG9yeSBtYXRlcmlhbDsgd2UgZGVzaWduYXRlIHRoZSBsb2FkZWQgdGV4dCB3aXRoIHRoZSBuYW1lIGBtb2J5YCwgc28gdGhhdCB3ZSBjYW4gcmVmZXIgdG8gaXQgYWdhaW4gbGF0ZXIgb24uIAoKYGBge3J9CnVybCA8LSAiaHR0cHM6Ly93d3cuZ3V0ZW5iZXJnLm9yZy9maWxlcy8yNzAxLzI3MDEtMC50eHQiCm1vYnkgPC0gcmVhZHRleHQodXJsKSB8PgogIHN0cl9zdWIoMjc3ODApCmBgYAoKVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgdGV4dCBpcyB3aGF0IGRhdGEgc2NpZW50aXN0cyBjYWxsICJkaXJ0eS4iIFRvIG1ha2UgaXQgdGlkeSwgd2UgdHJpbSB3aGl0ZXNwYWNlcyBhbmQgbmV3bGluZSBjaGFyYWN0ZXJzIGZyb20gdGhlIHRleHQsIGFuZCBsb3dlcmNhc2UgYWxsIGNoYXJhY3RlcnMuICAgCgpgYGB7cn0KbW9ieV9jaGFwdGVycyA8LSB1bmxpc3Qoc3RyX3NwbGl0KG1vYnksIGZpeGVkKCJDSEFQVEVSIikpKSB8PgogIHN0cl90cmltKCkgfD4KICBzdHJfcmVwbGFjZV9hbGwoIlxccysiLCAiICIpIHw+CiAgc3RyX3RvX2xvd2VyKCkKYGBgCgpXZSBzdG9yZSB0aGUgdGV4dCBpbiBhIHRhYmxlIGNhbGxlZCBgbW9ieV9kZmAuIAoKYGBge3IsIHJlc3VsdHM9J2hpZGUnfQptb2J5X2RmIDwtIHRpYmJsZSgiY2hhcHRlcnMiID0gbW9ieV9jaGFwdGVycykgfD4gCiAgc2xpY2UoLTEpCmBgYAoKSGVyZSBhcmUgd2hhdCB0aGUgZmlyc3QgZml2ZSBjaGFwdGVycyBvZiBNb2J5IERpY2sgbG9vayBsaWtlIGFmdGVyIHRpZHlpbmcuIAoKYGBge3IgZXZhbCA9IEZBTFNFfQpzbGljZV9oZWFkKG1vYnlfZGYsIG4gPSA1KQpgYGAKCmBgYHtyIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFLCBlY2hvID0gRkFMU0V9CmxpYnJhcnkoa2FibGVFeHRyYSkKCm1vYnlfY2hhcHRlcnNfdG1wIDwtIHVubGlzdChzdHJfc3BsaXQobW9ieSwgZml4ZWQoIkNIQVBURVIiKSkpIHw+CiAgc3RyX3RyaW0oKSB8PgogIHN0cl9yZXBsYWNlX2FsbCgiXFxzKyIsICIgIikgfD4KICBzdHJfdG9fbG93ZXIoKSB8PgogIHN0cl9zdWIoZW5kID0gMjAwKSAKICAKCmRpc3BfZGYgPC0gdGliYmxlKCJjaGFwdGVycyIgPSBtb2J5X2NoYXB0ZXJzX3RtcCkgfD4KICBzbGljZSgtMSkKCmtuaXRyOjprYWJsZSgKICBoZWFkKGRpc3BfZGYsIDUpLCBib29rdGFicyA9IFRSVUUpIHw+CiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwgZnVsbF93aWR0aCA9IEYpIHw+CiAgY29sdW1uX3NwZWMoMSwgd2lkdGggPSAiMzBlbSIpCmBgYAoKCiMjIyBQbG90dGluZyB3b3JkIHJlbGF0aW9uc2hpcHMgey19CgpOb3cgdGhhdCB3ZSBoYXZlIHRoZSBtYWluIHRleHQgc3RvcmVkIGluIHRhYnVsYXIgZm9ybSwgd2UgYXJlIHJlYWR5IHRvIGRvIHNvbWUgYW5hbHlzaXMuIExldCB1cyBsb29rIGF0IHNvbWUgYXNzb2NpYXRpb25zIGJldHdlZW4gd29yZHMgaW4gdGhlIHRleHQsIGZvciBpbnN0YW5jZSwgYmV0d2VlbiAic2hpcCIgYW5kICJzZWEiLCBhbmQgYmV0d2VlbiAiZ29kIiBhbmQgInNlYSIuCgpXZSBjb21wdXRlIGluIGVhY2ggY2hhcHRlciBob3cgbWFueSB0aW1lcyBlYWNoIG9mIHRoZSB3b3JkcyBvY2N1cjogInNoaXAiLCAic2VhIiwgYW5kICJnb2QiLiBUaGUgcmVzdWx0cyBhcmUgc3RvcmVkIGFzIG5ldyBjb2x1bW5zIGFwcGVuZGVkIHRvIHRoZSB0YWJsZSBgbW9ieV9kZmAuCgpgYGB7cn0KbW9ieV9kZiA8LSBtb2J5X2RmIHw+CiAgbXV0YXRlKAogICAgY2hhcHRlcl9udW0gPSByb3dfbnVtYmVyKCksCiAgICBzaGlwID0gc3RyX2NvdW50KGNoYXB0ZXJzLCAic2hpcCIpLAogICAgc2VhID0gc3RyX2NvdW50KGNoYXB0ZXJzLCAic2VhIiksCiAgICBnb2QgPSBzdHJfY291bnQoY2hhcHRlcnMsICJnb2QiKQogICkgCmBgYAoKSGVyZSBpcyB3aGF0IHRob3NlIG5ldyBjb2x1bW5zIGxvb2sgbGlrZS4gCgpgYGB7cn0KbW9ieV9kZiB8PgogIHNlbGVjdChjaGFwdGVyX251bSwgc2hpcCwgc2VhLCBnb2QpCmBgYAoKV2UgZHJhdyBhIHNjYXR0ZXIgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gdGhlIHBhaXJzICJzaGlwIiBhbmQgInNlYSIsIGFuZCAiZ29kIiBhbmQgInNlYSIuIFRoZSBmb3JtZXIgaXMgc2hvd24gaW4gY3lhbiBhbmQgdGhlIGxhdHRlciBpbiByZWQuIAoKYGBge3IgbWVzc2FnZSA9IEZBTFNFfQpnZ3Bsb3QobW9ieV9kZikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBzZWEsIHkgPSBzaGlwLCBjb2xvciA9ICJzaGlwIikpICsgCiAgZ2VvbV9wb2ludChhZXMoeCA9IHNlYSwgeSA9IGdvZCwgY29sb3IgPSAiZ29kIikpICsgCiAgeWxhYigiY291bnQiKQpgYGAKCldlIHNlZSBhIHN0cm9uZyBhc3NvY2lhdGlvbiBiZXR3ZWVuICJzZWEiIGFuZCAic2hpcCIgc2luY2UgY2hhcHRlcnMgdGhhdCBtZW50aW9uIHRoZSB3b3JkICJzZWEiIGEgbG90IHRlbmQgdG8gYWxzbyBtZW50aW9uICJzaGlwIiBhIHdob2xlIGxvdCBhcyB3ZWxsLiBUaGUgcmVsYXRpb25zaGlwIGJldHdlZW4gInNlYSIgYW5kICJnb2QiIGlzIGxlc3MgYXBwYXJlbnQuIFRoZXJlIGlzIG9uZSBjaGFwdGVyIHdoZXJlICJnb2QiIGFuZCAic2VhIiBib3RoIG9jY3VyIGZyZXF1ZW50bHksIGJ1dCBvdmVyYWxsIGl0IHNlZW1zIHRoYXQgdGhlIG9jY3VycmVuY2VzIG9mICJnb2QiIGhhdmUgbm90aGluZyB0byBkbyB3aXRoIG9jY3VycmVuY2VzIG9mICJzZWEiLiAKCkluZGVlZCwgd29yZCBjb3VudHMgY2FuIG9ubHkgdGFrZSB1cyBzbyBmYXIuIEJ1dCB0aGV5IGFyZSBhIGZpcnN0IHN0ZXAgaW4gdGhlIGludGVycHJldGF0aXZlIHByb2Nlc3MuIEZvciBpbnN0YW5jZSwgd2h5IGRvZXMgaXQgc2VlbSB0aGF0IHRoZXJlIGlzIG5vIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBzZWEsIHdoZXJlIG1vc3Qgb2YgdGhlIGFjdGlvbiB0YWtlcyBwbGFjZSwgYW5kIHJlbGlnaW9uLCBhcyBleGVtcGxpZmllZCBieSB0aGUgb2NjdXJyZW5jZXMgb2YgdGhlIHdvcmQgImdvZCI/IE1hY2hpbmUtYXNzaXN0ZWQgYW5hbHlzaXMgb2YgdGV4dHMgaW4gdGhpcyBtYW5uZXIsIHdoaWNoIGV4dGVuZHMgd2VsbCBiZXlvbmQgd29yZCBjb3VudHMsIGhhcyBiZWNvbWUgc28gcG9wdWxhciB0aGF0IGFuIGludGVyZGlzY2lwbGluYXJ5IGZpZWxkIGNhbGxlZCBbRGlnaXRhbCBIdW1hbml0aWVzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9EaWdpdGFsX2h1bWFuaXRpZXMpICBoYXMgYmVjb21lIGRlZGljYXRlZCB0byBpdHMgc3R1ZHkuIAoKIyMjIEEgcm91Z2ggb3V0bGluZSB7LX0KCk91ciB0d28gaW50cm9kdWN0b3J5IGV4YW1wbGVzIGhhdmUgaG9wZWZ1bGx5IHNob3duIHlvdSBhIGdsaW1wc2Ugb2Ygd2hhdCBkYXRhIHNjaWVuY2Ugd29yayBsb29rcyBsaWtlLiBIZXJlIGlzIGFuIG91dGxpbmUgb2Ygd2hhdCB5b3Ugd2lsbCBsZWFybiBpbiB0aGlzIGNvdXJzZTogCgoqIFdlIGJlZ2luIHdpdGggYSBjb3ZlcmFnZSBvZiB0aGUgZnVuZGFtZW50YWxzIG9mIFIgcHJvZ3JhbW1pbmcuCiogV2Ugd2lsbCBtb3ZlIG9uIHRvIGxlYXJuaW5nIGhvdyB0aGUgYHRpZHl2ZXJzZWAgY2FuIGJlIHVzZWQgZm9yIGRhdGEgdGlkeWluZyBhbmQgdmlzdWFsaXphdGlvbi4KKiBXZSB0aGVuIHN0dWR5IGhvdyB0byBleHRyYWN0ICppbnNpZ2h0cyogZnJvbSBvdXIgZGF0YSB1c2luZyBzdGF0aXN0aWNhbCBpbmZlcmVuY2luZyB0ZWNobmlvcXVlcy4gCiogV2UgZW5kIHdpdGggZ2VuZXJhdGluZyAqbW9kZWxzKiBmcm9tIGRhdGEuIFdlIHRoZW4gdXNlIHRoZXNlIHRvIG1ha2UgKnByZWRpY3Rpb25zKiBhYm91dCBwb3NzaWJsZSBvdXRjb21lcyBmb3IgInVua25vd24iIG9ic2VydmF0aW9ucyB1c2luZyByZWdyZXNzaW9uIGFuZCB0ZXh0IGFuYWx5c2lzIHRlY2huaXF1ZXMuICAKCkkgaG9wZSB0aGF0IHlvdSB3aWxsIGZpbmQgdGhlIGpvdXJuZXkgaW50ZXJlc3RpbmcuCgojIEluc3RhbGxhdGlvbgoKVG8gd2F0Y2ggdmlkZW9zIGFib3V0IEluc3RhbGxpbmcgUiBhbmQgUlN0dWRpbywgZ28gdG8gdGhlICoqRnVydGhlciBJbmZvcm1hdGlvbioqIHNlY3Rpb24gYmVsb3cuCgpIZXJlIGFyZSB0aGUgc3RlcHMKCi0gICBHbyB0byBbQ1JBTl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvKSAoQ29tcHJlaGVuc2l2ZSBSIEFyY2hpdmUgTmV0d29yaykgdG8gaW5zdGFsbCBSLiBDaG9vc2UgdGhlIGFwcHJvcHJpYXRlIGRvd25sb2FkIChsaWtlbHkgZWl0aGVyIE1hYyBvciBQQykuIElmIHlvdSBoYXZlIGEgTWFjLCB5b3Ugc2hvdWxkIHRoZW4gY2hvb3NlIHRoZSBsYXRlc3QgcmVsZWFzZSB0aGF0IGVuZHMgaW4gYC5wa2dgLiBJZiB5b3UgaGF2ZSBhIFBDLCB5b3Ugc2hvdWxkIGNsaWNrIG9uIGBiYXNlYC4gT25jZSBpdCBkb3dubG9hZHMsIHlvdSB3aWxsIG5lZWQgdG8gY2xpY2sgb24gdGhlIGZpbGUgdGhhdCB3YXMgZG93bmxvYWRlZCBpbiBvcmRlciB0byBpbnN0YWxsIGl0LiBZb3UgY2FuIGNsaWNrIHRocm91Z2ggdGhlIHByb21wdHMgZHVyaW5nIGluc3RhbGxhdGlvbi4gT25jZSBmaW5pc2hlZCwgaXQgc2hvdWxkIHRlbGwgeW91IHRoYXQgaXQgd2FzIGluc3RhbGxlZCBzdWNjZXNzZnVsbHkuIChJZiB5b3UgaGF2ZSBhIE1hYywgeW91IHNob3VsZCBhbHNvIGRvd25sb2FkIGFuZCBpbnN0YWxsIFhRdWFydHogW2hlcmVdKGh0dHBzOi8vd3d3LnhxdWFydHoub3JnLykuKQoKLSAgIERvd25sb2FkIFJTdHVkaW8gZnJvbSBbdGhlaXIgd2Vic2l0ZV0oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC8jZG93bmxvYWQpLiBZb3Ugd2FudCB0aGUgZnJlZSBSU3R1ZGlvIERlc2t0b3AgdmVyc2lvbi4gQ2hvb3NlIHRoZSBvbmUgdGhhdCBtYXRjaGVzIHlvdXIgb3BlcmF0aW5nIHN5c3RlbSAob25lIHdpbGwgbGlrZWx5IGJlIHN1Z2dlc3RlZCB0byB5b3UgYXQgdGhlIHRvcCBvZiB0aGUgcGFnZSkuIEZvbGxvdyB0aGUgcHJvbXB0cy4gT24gYSBNYWMsIGJlIHN1cmUgdG8gZHJvcCBSU3R1ZGlvIGludG8gdGhlIGFwcGxpY2F0aW9ucyBmb2xkZXIgYXQgdGhlIGVuZCBvZiB0aGUgZG93bmxvYWQuIElmIHlvdSBoYXZlIGRvd25sb2FkZWQgaXQgYmVmb3JlLCBpdCB3aWxsIGFzayBpZiB5b3Ugd2FudCB0byB1c2UgdGhlIG5ld2VyIHZlcnNpb24uIENob29zZSB5ZXMuCgojIENvdXJzZSBEb3dubG9hZHMKCkhlcmUgeW91IGNhbiBkb3dubG9hZCBzb21lIGZpbGVzIHRoYXQgd2lsbCBiZSB1c2VmdWwgZHVyaW5nIHRoZSBjb3Vyc2UuIFRoZSBtb3N0IGltcG9ydGFudCB0aGluZyB0byByZW1lbWJlciBpcyB0byBrZWVwIHRyYWNrIG9mIHdoZXJlIHlvdSBhcmUgZG93bmxvYWRpbmcgZmlsZXMgdG8uIEF2b2lkIHNpbXBseSB1c2luZyB0aGUgZGVmYXVsdCBEb3dubG9hZHMgZm9sZGVyIC0gaW5zdGVhZCwgSSByZWNvbW1lbmQgYW4gb3JnYW5pc2VkIEZvbGRlciBzeXN0ZW06CgojIyMgRm9sZGVyIHN5c3RlbQoKQSByZWFsbHkgZWFzeSB3YXkgdG8gZ2V0IGNvbmZ1c2VkIHZlcnkgcXVpY2tseSB3aGVuIGRlYWxpbmcgd2l0aCBkYXRhIChpbiBmYWN0IGFueSBraW5kIG9mIGZpbGUpIGlzIHRvIGhhdmUgYmFkbHkgb3JnYW5pc2VkIGZpbGluZyBhbmQgZm9sZGVycy4gSSByZWNvbW1lbmQgdGhlIGZvbGxvd2luZyBGb2xkZXIgc3RydWN0dXJlIGZvciB5b3UgdG8gZG93bmxvYWQgYW5kIHNhdmUuIERvICoqTk9UKiogc2F2ZSB0aGlzIGluIHlvdXIgKipEb3dubG9hZHMqKiBmb2xkZXIsIGJ1dCBzb21ld2hlcmUgc2VwYXJhdGUgc3VjaCBhcyB5b3VyIERlc2t0b3Agb3IgRG9jdW1lbnRzLiBGb3IgV2luZG93cyB1c2VycywgYXZvaWQgcHV0dGluZyB0aGUgRm9sZGVyIGluIE9uZURyaXZlIGFzIHRoYXQgY2FuIGxlYWQgdG8gc29tZSBwcm9ibGVtcyBsYXRlciAoc2VlICoqUHJvYmxlbXMgaW5zdGFsbGluZyBwYWNrYWdlcyoqKS4KCmBgYHtyLCBlY2hvPUZBTFNFfQojIyBEaXJlY3RvcnkgcGF0aCBhcyBhbiBleGFtcGxlCmxpYnJhcnkoZG93bmxvYWR0aGlzKQpkb3dubG9hZF9kaXIoCiAgcGF0aCA9ICIvVXNlcnMvdGltbWFyY2hhbmQvRG93bmxvYWRzL0lTU19EQVRBU0NJIiwKICBvdXRwdXRfbmFtZSA9ICJJU1NfREFUQVNDSSIsCiAgYnV0dG9uX2xhYmVsID0gIkZvbGRlciBzdHJ1Y3R1cmUiLAogIGJ1dHRvbl90eXBlID0gInN1Y2Nlc3MiLAogIGhhc19pY29uID0gVFJVRSwKICBpY29uID0gImZhIGZhLXNhdmUiLAogIHNlbGZfY29udGFpbmVkID0gRkFMU0UKKQpgYGAKCk9uY2UgeW91IHVuemlwIHRoZSBmaWxlLCB5b3Ugc2hvdWxkIHNlZSBmb2xkZXJzIGZvcjoKCi0gICBkYXRhCgotICAgZmlndXJlcwoKLSAgIHByb2Jfc2V0cwoKLSAgIHJfZG9jcwoKQXMgd2VsbCBhczoKCi0gICBpc3NfZGF0YV9zY2llbmNlLlJwcm9qCgpXaGljaCBpcyBhIHByb2plY3QgbGluayB0aGF0IHNldHMgdGhlIHdvcmtpbmcgZGlyZWN0b3J5IG9mIHlvdXIgUiBzZXNzaW9uIHRvIHRoYXQgZm9sZGVyIHN0cnVjdHVyZS4KCkFzIHdlIHByb2dyZXNzIHRocm91Z2ggdGhlIGNvdXJzZSwgeW91IHdpbGwgYmUgYWJsZSB0byBkb3dubG9hZCBSIGNvZGUgYW5kIGRhdGEgZXRjIGZyb20gTW9vZGxlIG9yIGVsc2V3aGVyZSwgYW5kIHB1dCBpdCBpbnRvIHRoZXNlIGZvbGRlcnMuCgojIyMgV2Vla2x5IHJlZmxlY3Rpb25zCgpUaGUgZmlyc3QgciBjb2RlIGZvciB5b3UgdG8gZG93bmxvYWQgaXMgbmVjZXNzYXJ5IGZvciB5b3VyIGhvbWV3b3JrIGVhY2ggd2VlazogYSBkb2N1bWVudCBvZiBub3RlcyBmb3IgcmVmbGVjdGluZyBvbiB3aGF0IHlvdSBsZWFybmVkIGluIGNsYXNzLiBTYXZlIHRoaXMgaXMgaW4geW91ciByX2RvY3MgZm9sZGVyOgoKYGBge3IsIGVjaG89RkFMU0V9CiMgZG93bmxvYWRfZmlsZSgKIyAgIHBhdGggPSAiLi4vZG93bmxvYWRzL3dlZWtseV9ub3Rlcy5SbWQiLAojICAgYnV0dG9uX2xhYmVsID0gIkRvd25sb2FkIFdlZWtseSBOb3RlcyIsCiMgICBidXR0b25fdHlwZSA9ICJpbmZvIiwKIyAgIGhhc19pY29uID0gVFJVRSwKIyAgIGljb24gPSAiZmEgZmEtc2F2ZSIsCiMgICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCiMgKQpgYGAKCiMjIyBUZW1wbGF0ZXMKClRoZXNlIHRlbXBsYXRlcyB3aWxsIGJlIHVzZWZ1bCB3aGVuZXZlciB5b3Ugd2FudCB0byB0cnkgb3V0IFIgY29kZSB1c2luZyBhIHNpbXBsZSBSIHNjcmlwdCBvciBSTWFya2Rvd24gZmlsZS4gQSBnb29kIHBsYWNlIGZvciB0aGVtIGlzIHRoZSByX2RvY3MgZm9sZGVyIHRvbzoKCmBgYHtyLCBlY2hvPUZBTFNFfQojIGRvd25sb2FkX2ZpbGUoCiMgICBwYXRoID0gIi4uL2Rvd25sb2Fkcy9SX01hcmtkb3duX1RlbXBsYXRlLlJtZCIsCiMgICBidXR0b25fbGFiZWwgPSAiRG93bmxvYWQgUl9NYXJrZG93bl9UZW1wbGF0ZSIsCiMgICBidXR0b25fdHlwZSA9ICJpbmZvIiwKIyAgIGhhc19pY29uID0gVFJVRSwKIyAgIGljb24gPSAiZmEgZmEtc2F2ZSIsCiMgICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCiMgKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQojIGRvd25sb2FkX2ZpbGUoCiMgICBwYXRoID0gIi4uL2Rvd25sb2Fkcy9kYXRhX2V4cGxvcmF0aW9uX3RlbXBsYXRlLlIiLAojICAgYnV0dG9uX2xhYmVsID0gIkRvd25sb2FkIEV4cG9yaW5nIGRhdGEgUiB0ZW1wbGF0ZSIsCiMgICBidXR0b25fdHlwZSA9ICJpbmZvIiwKIyAgIGhhc19pY29uID0gVFJVRSwKIyAgIGljb24gPSAiZmEgZmEtc2F2ZSIsCiMgICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCiMgKQpgYGAKCiMjIyAKCiMjIyBQcm9ibGVtIHNldHMKCkR1cmluZyB0aGUgY291cnNlLCBzb21ldGltZXMgeW91ciBob21ld29yayB3aWxsIGJlIHByb2JsZW0gc2V0cy4gWW91IGNhbiBkb3dubG9hZCB0aGVtIGhlcmUgYW5kIHB1dCB0aGVtIGludG8geW91ciBwcm9iX3NldHMgZm9sZGVyIDoKCmBgYHtyLCBlY2hvPUZBTFNFfQojIyBEaXJlY3RvcnkgcGF0aCBhcyBhbiBleGFtcGxlCmRvd25sb2FkX2RpcigKICBwYXRoID0gIi4uL3Byb2Jfc2V0cyIsCiAgb3V0cHV0X25hbWUgPSAicHJvYl9zZXRzIiwKICBidXR0b25fbGFiZWwgPSAiRG93bmxvYWQgUHJvYmxlbSBTZXRzIiwKICBidXR0b25fdHlwZSA9ICJzdWNjZXNzIiwKICBoYXNfaWNvbiA9IFRSVUUsCiAgaWNvbiA9ICJmYSBmYS1zYXZlIiwKICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCikKYGBgCgojIyMgRXhhbXBsZSBwcm9qZWN0cyAoT3B0aW9uYWwpCgpIZXJlIHlvdSBjYW4gZG93bmxvYWQgZXhhbXBsZSBwcm9qZWN0IGZpbGVzIGZyb20gSVNTIHN0dWRlbnRzLiBJZiB5b3UganVzdCB3YW50IHRvIHNlZSB0aGUgb3V0cHV0IGluIGh0bWwgZm9ybSwgZ28gdG8gdGhlIFtSZXNvdXJjZXNdKGh0dHBzOi8vbW9vZGxlLmlzcy5nYWt1c2h1aW4uYWMuanAvbW9vZGxlL21vZC9wYWdlL3ZpZXcucGhwP2lkPTQ4NTYyKSBzZWN0aW9uIG9uIE1vb2RsZS4KCmBgYHtyLCBlY2hvPUZBTFNFfQojIGRvd25sb2FkX2ZpbGUoCiMgICBwYXRoID0gIi4uL2Rvd25sb2Fkcy9leGFtcGxlX3Byb2plY3QuUm1kIiwKIyAgIGJ1dHRvbl9sYWJlbCA9ICJFeGFtcGxlIFByb2plY3QgMSIsCiMgICBidXR0b25fdHlwZSA9ICJpbmZvIiwKIyAgIGhhc19pY29uID0gVFJVRSwKIyAgIGljb24gPSAiZmEgZmEtc2F2ZSIsCiMgICBzZWxmX2NvbnRhaW5lZCA9IEZBTFNFCiMgKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQojIGRvd25sb2FkX2ZpbGUoCiMgICBwYXRoID0gIi4uL2Rvd25sb2Fkcy9leGFtcGxlX3Byb2plY3RfMi5SbWQiLAojICAgYnV0dG9uX2xhYmVsID0gIkV4YW1wbGUgUHJvamVjdCAyIiwKIyAgIGJ1dHRvbl90eXBlID0gImluZm8iLAojICAgaGFzX2ljb24gPSBUUlVFLAojICAgaWNvbiA9ICJmYSBmYS1zYXZlIiwKIyAgIHNlbGZfY29udGFpbmVkID0gRkFMU0UKIyApCmBgYAoKIyBTZXR0aW5nIHVwIGZvciBzdWNjZXNzCgpUaGVzZSBhcmUgc29tZSBzdGVwcyB5b3Ugc2hvdWxkIHRha2UgdG8gc2V0IHlvdXJzZWxmIHVwIGZvciBhbiBlYXNpZXIgdGltZSB1c2luZyBSIGFuZCBSU3R1ZGlvLgoKLSAgIENyZWF0ZSBhIGZvbGRlciBvbiB5b3VyIGRlc2t0b3AsIGluIHlvdXIgRG9jdW1lbnRzIGZvbGRlciwgb3Igc29tZSBvdGhlciByZWFzb25hYmxlIGxvY2F0aW9uIG9uIHlvdXIgY29tcHV0ZXIuIFRoaXMgc2hvdWxkIE5PVCBiZSBpbiB5b3VyIGRvd25sb2Fkcy4gTGV0IG1lIHNheSB0aGF0IGFnYWluLCBtb3JlIGxvdWRseSwgKipUSElTIFNIT1VMRCBOT1QgQkUgSU4gWU9VUiBET1dOTE9BRFMqKi4gSSByZWNvbW1lbmQgeW91IHVzZSB0aGUgKipGb2xkZXIgc3RydWN0dXJlKiogb3V0bGluZWQgYWJvdmUsIGFuZCBhdm9pZCB1c2luZyAqKk9uZURyaXZlKiogaWYgeW91IGFyZSBhIFdpbmRvd3MgdXNlci4KCi0gICBTYXZlIG5ldyBSIHNjcmlwdHMgYW5kIFJNYXJrZG93biBmaWxlcyB0byB0aGUgY291cnNlIGZvbGRlci4geW91IGNyZWF0ZWQsICoqTk9UKiogdG8geW91ciBkb3dubG9hZHMuIFRoZSBiZXN0IHRvIHNhdmUgdGhlbSBwbGFjZSBpcyB0aGUgKipyX2RvY3MqKiBmb2xkZXIuIEFuZCBzYXZlIG9mdGVuISBUaGlzIGlzIG5vdCBsaWtlIEdvb2dsZSBkb2NzLiBJdCB3aWxsIG5vdCwgaW4gZ2VuZXJhbCwgYXV0byBzYXZlIGZvciB5b3UuCgotICAgV2hlbiB5b3UgZG93bmxvYWQgcmVzb3VyY2VzIGZyb20gTW9vZGxlLCBzYXZlIHRoZW0gdG8gdGhlIGNvdXJzZSBmb2xkZXIgYXMgd2VsbDogKmNzdiBmaWxlcyogZXRjIHRvIHRoZSAqKmRhdGEqKiBmb2xkZXIsIGFuZCBSIHNjcmlwdHMgYW5kIFJNYXJrZG93biBmaWxlcyB0byB0aGUgKipyX2RvY3MqKiBmb2xkZXIuIE9uIG1vc3QgY29tcHV0ZXJzLCBkb3dubG9hZGVkIGZpbGVzIHdpbGwgYmUgc2F2ZWQgdG8geW91ciBkb3dubG9hZHMuIFlvdSBjYW4gZWl0aGVyIGNoYW5nZSB0aGUgc2V0dGluZ3Mgb3IgYmUgc3VyZSB0byBzYXZlIGZpbGVzIHNvbWV3aGVyZSBlbHNlIGFmdGVyIGRvd25sb2FkaW5nLiBJZiB5b3UgdXNlIGEgTWFjLCBkbyBub3QgdXNlIFNhZmFyaSB3aGVuIGRvd25sb2FkaW5nIFIgbWFya2Rvd24gZmlsZXMgZnJvbSBNb29kbGUuIFVzZSBzb21lIG90aGVyIGJyb3dzZXIgKENocm9tZSwgTW96aWxsYSwgZXRjLikuIFNhZmFyaSB3aWxsIGFkZCBhIC50eHQgZXh0ZW5zaW9uIHRvIHRoZSAucm1kIGZpbGUgYW5kIG1ha2VzIGl0IGRpZmZpY3VsdCBmb3IgeW91IHRvIGZpeCBpdC4KCi0gICBDaGFuZ2UgZ2xvYmFsIHNldHRpbmdzISBHbyB0byBUb29scyAtLVw+IEdsb2JhbCBvcHRpb25zLiBPbiB0aGUgR2VuZXJhbCB0YWIsIG5leHQgdG8gKlNhdmUgd29ya3NwYWNlIHRvIC5SRGF0YSBvbiBleGl0KiwgY2hvb3NlICpOZXZlciogYW5kIHVuY2hlY2sgdGhlIGJveCBuZXh0IHRvICpSZXN0b3JlIC5SZGF0YSBpbnRvIHdvcmtzcGFjZSBhdCBzdGFydHVwKi4gWW91IGNhbiBhbHNvIGdvIHRvIHRoZSBBcHBlYXJhbmNlIHRhYiB0byBjdXN0b21pemUgdGhlIGxvb2sgb2YgUlN0dWRpby4KCkNoZWNrIG91dCB0aGlzIHZpZGVvIHdoaWNoIGV4cGxhaW5zIHRoaXMgcG9pbnQsIGFuZCBhbHNvIHNob3dzIHlvdSBob3cgdG8gYGtuaXRgIHlvdXIgZmlyc3QgUk1hcmtkb3duIGRvY3VtZW50LgoKPGlmcmFtZSB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9PTjNVUV9HRENvdyIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhY2NlbGVyb21ldGVyOyBhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSIgYWxsb3dmdWxsc2NyZWVuIGRhdGEtZXh0ZXJuYWw9IjEiPgoKPC9pZnJhbWU+CgotICAgU3BlbGwgY2hlY2suIFRoZXJlIGlzIGEgc3BlbGwgY2hlY2sgYnV0dG9uIChBQkMgd2l0aCBhIGNoZWNrIG1hcmsgdW5kZXJuZWF0aCBpdCkuIFlvdSBzaG91bGQgdXNlIHRoYXQgZm9yIHlvdXIgYXNzaWdubWVudHMuIEluIHRoaXMgbmV3ZXN0IHZlcnNpb24gb2YgUlN0dWRpbyB0aGVyZSBpcyBhbHNvIGlubGluZSBzcGVsbGNoZWNrIHNvIHdvcmRzIGl0IGRvZXMgbm90IHJlY29nbml6ZSB3aWxsIGhhdmUgYSBzcXVpZ2dseSBsaW5lIHVuZGVyIHRoZW0uCgotICAgRG9uJ3QgYmUgYWZyYWlkIHRvIHVzZSB0aGUgaW50ZXJuZXQgdG8gc2VhcmNoIGZvciBhbnN3ZXJzIHRvIHlvdXIgcXVlc3Rpb25zLiBJIGRvIHRoaXMgYWxsIHRoZSB0aW1lLiBBbmQgd2hlbiBJIHNheSBhbGwgdGhlIHRpbWUsIEkgbWVhbiBldmVyeSBzaW5nbGUgdGltZSBJIHVzZSBSLiBBIGdvb2QgcGxhY2UgdG8gc3RhcnQgYXJlIHVzaW5nIHRoZSBsaW5rcyBJIHB1dCBvbiBNb29kbGU6CgogICAgLSAgIFtSc2Vla10oaHR0cHM6Ly9yc2Vlay5vcmcvKSBBIGN1c3RvbWlzZWQgc2VhcmNoIGVuZ2luZSB3aGljaCB3aWxsIHJldHVybiBvbmx5IGNvbnRlbnQgcmVsYXRlZCB0byBSCgogICAgLSAgIFtRaWl0YV0oaHR0cHM6Ly9xaWl0YS5jb20vKSBBIHBvcHVsYXIgc2l0ZSBmb3IgYXNraW5nIGNvZGluZyBxdWVzdGlvbnMgaW4gSmFwYW5lc2UKCiMgVG91ciBvZiBSU3R1ZGlvCgpXYXRjaCB0aGUgdmlkZW8gYmVsb3cgZm9yIGEgdG91ciBvZiBSU3R1ZGlvLiBNb3N0IG9mIHdoYXQgaXMgY292ZXJlZCBpbiB0aGUgdmlkZW8gaXMgYWxzbyB3cml0dGVuIG91dCBpbiB0aGUgZGV0YWlscyBvZiB0aGlzIHNlY3Rpb24uCgo8aWZyYW1lIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL0ZLbDRWMWxHa21VIiBmcmFtZWJvcmRlcj0iMCIgYWxsb3c9ImFjY2VsZXJvbWV0ZXI7IGF1dG9wbGF5OyBlbmNyeXB0ZWQtbWVkaWE7IGd5cm9zY29wZTsgcGljdHVyZS1pbi1waWN0dXJlIiBhbGxvd2Z1bGxzY3JlZW4gZGF0YS1leHRlcm5hbD0iMSI+Cgo8L2lmcmFtZT4KClRoZXJlIGFyZSBmb3VyIG1haW4gcGFuZXMgaW4gUlN0dWRpby4gSSB3aWxsIGRpc2N1c3MgYWxsIGZvdXIuIElmIHlvdSBldmVyIHdhbnQgdG8gY2hhbmdlIHRoZSBsYXlvdXQsIHlvdSBjYW4gZG8gdGhhdCBieSBjbGlja2luZyB0aGUgZG93biBhcnJvdyBpbiB0aGUgbWVudSBhdCB0aGUgdG9wIG9mIFJTdHVkaW8gdGhhdCBsb29rcyBsaWtlIGEgd2luZG93IHdpdGggZm91ciBwYW5lcy4gQW5kLCBpZiB5b3UgZXZlciBsb3NlIG9uZSBvciBtb3JlIG9mIHRoZSBwYW5lcywgY2xpY2sgdGhhdCBzYW1lIGRvd24gYXJyb3cgYW5kIGNob29zZSAqU2hvdyBBbGwgUGFuZXMqLgoKIyMgU291cmNlCgpUaGUgKm1haW4qIHBhbmUgaW4gdGhlIHRvcCBsZWZ0IGhhcyB0aGUgZmlsZSB5b3UgYXJlIHdvcmtpbmcgZnJvbS4gSW4gdGhpcyBjbGFzcywgd2Ugd2lsbCB3b3JrIHdpdGggUiBNYXJrZG93biBmaWxlcywgLnJtZCBmaWxlcyBmb3Igc2hvcnQuIEkgdGFsayBhYm91dCB0aG9zZSBtb3JlIGJlbG93LgoKIyMgQ29uc29sZQoKVGhlICpjb25zb2xlKiBpbiB0aGUgbG93ZXIgbGVmdCBpcyB3aGVyZSB0aGUgY29kZSBpcyBldmFsdWF0ZWQuIFNpbmNlIHdlIGNhbiBhbHNvIHNlZSB0aGUgY29kZSBldmFsdWF0ZWQgd2l0aGluIHRoZSAucm1kIGZpbGUsIEkgb2Z0ZW4ga2VlcCB0aGUgY29uc29sZSBtaW5pbWl6ZWQuIEkgd2lsbCBzb21ldGltZXMgZG8gc29tZSBxdWljayBtYXRoIGluIHRoZSBjb25zb2xlLiBUaGUgYD5gIGlzIHRoZSBwcm9tcHQsIGluZGljYXRpbmcgd2hlcmUgeW91IHNob3VsZCBzdGFydCB5b3VyIGNvZGUuCgpXaGVuIHlvdSBrbml0IChjb21waWxlKSB5b3VyIGRvY3VtZW50LCB0aGlzIHBhbmUgd2lsbCBzaG93IHRoZSBjb21wbGljYXRpb24gcHJvY2VzcyBpbiBhIHRhYiBjYWxsZWQgKlIgTWFya2Rvd24qLiBJZiB5b3UgZ2V0IGFuIGVycm9yLCB5b3Ugd2lsbCBzZWUgaXQgdGhlcmUuCgojIyBFbnZpcm9ubWVudCwgSGlzdG9yeSwgQ29ubmVjdGlvbnMsIFR1dG9yaWFsCgpUaGUgcGFuZSBpbiB0aGUgdXBwZXIgcmlnaHQgaGFzIGEgZmV3IHRhYnMgb2YgaW50ZXJlc3QuIFRoZSAqRW52aXJvbm1lbnQqIHRhYiBzaG93cyBhbnl0aGluZyB0aGF0IGhhcyBiZWVuIHNhdmVkIHRvIHRoZSB3b3Jrc3BhY2UuIFNvLCBpZiB5b3UgcmVhZCBpbiBhIGRhdGFzZXQgb3IgY3JlYXRlIGEgbmV3IG5hbWVkIGRhdGFzZXQsIHZhcmlhYmxlLCBldGMuLCBpdCB3aWxsIHNob3cgdXAgdGhlcmUuIFlvdSBjYW4gZG8gc29tZSBiYXNpYyBleHBsb3JhdGlvbiBvZiB0aG9zZSBpdGVtcyBieSBjbGlja2luZyBvbiB0aGVtIGluIHRoZSBFbnZpcm9ubWVudC4KClRoZSAqSGlzdG9yeSogdGFiIHNob3dzIHlvdXIgaGlzdG9yeSBvZiBjb2RlIHRoYXQgaGFzIGJlZW4gcnVuIGluIHRoaXMgc2Vzc2lvbi4gSXQgaXMgc29tZXRpbWVzIGhlbHBmdWwgaWYgeW91IHdhbnQgdG8gZ2V0IHRvIGFuIG9sZCBwaWVjZSBvZiBjb2RlIHRoYXQgeW91IGRlbGV0ZWQgZnJvbSB5b3VyIC5ybWQgZmlsZS4KClRoZSAqVHV0b3JpYWxzKiB0YWIgaXMgbmV3LiBJIHdvdWxkIGVuY291cmFnZSB5b3UgdG8gZXhwbG9yZSB0aGUgcmVzb3VyY2VzIGF2YWlsYWJsZSB0aGVyZS4KCiMjIEZpbGVzLCBQbG90cywgUGFja2FnZXMsIEhlbHAsIFZpZXdlcgoKSSB0aGluayB0aGUgbW9zdCBpbXBvcnRhbnQgdHdvIHRhYnMgaW4gdGhlIGxvd2VyIHJpZ2h0IGFyZSAqRmlsZXMqIGFuZCAqSGVscCouIEluIHRoZSAqRmlsZXMqIHRhYiwgeW91IGNhbiBuYXZpZ2F0ZSB0byB2YXJpb3VzIGxvY2F0aW9ucyBvbiB5b3VyIGNvbXB1dGVyLiBCeSBkZWZhdWx0LCBpdCB3aWxsIGJlIGluIHRoZSBmb2xkZXIgd2hlcmUgdGhlIGZpbGUgeW91IGhhdmUgb3BlbiBpcyBsb2NhdGVkLgoKVGhlICpIZWxwKiB0YWIgaXMgd2hlcmUgeW91IGNhbiBnbyB0byBzZWFyY2ggZm9yIGhlbHAgd2l0aCBSIGZ1bmN0aW9ucy4gWW91IGNhbiB0eXBlIGluIGEgZnVuY3Rpb24gbmFtZSBhbmQgZ28gdG8gdGhhdCBmdW5jdGlvbidzIGhlbHAgcGFnZS4KCiMgRnVydGhlciBpbmZvcm1hdGlvbgoKVGhlIGZvbGxvd2luZyB2aWRlb3Mgc2hvdWxkIGhlbHAgd2l0aCBzb21lIGFzcGVjdHMgb2YgdGhlIHNldHRpbmcgdXAgYW5kIHRyb3VibGVzaG9vdGluZzoKCiMjIEluc3RhbGxpbmcgUiBhbmQgUlN0dWRpbyBvbiBXaW5kb3dzCgo8aWZyYW1lIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkL18yc2V3R0NBMHk0IiBmcmFtZWJvcmRlcj0iMCIgYWxsb3c9ImFjY2VsZXJvbWV0ZXI7IGF1dG9wbGF5OyBlbmNyeXB0ZWQtbWVkaWE7IGd5cm9zY29wZTsgcGljdHVyZS1pbi1waWN0dXJlIiBhbGxvd2Z1bGxzY3JlZW4gZGF0YS1leHRlcm5hbD0iMSI+Cgo8L2lmcmFtZT4KCiMjIEluc3RhbGxpbmcgUiBhbmQgUlN0dWRpbyBvbiBhIE1hYwoKPGlmcmFtZSB3aWR0aD0iNTYwIiBoZWlnaHQ9IjMxNSIgc3JjPSJodHRwczovL3d3dy55b3V0dWJlLmNvbS9lbWJlZC9MYW5Cb3pYSmpPayIgZnJhbWVib3JkZXI9IjAiIGFsbG93PSJhY2NlbGVyb21ldGVyOyBhdXRvcGxheTsgZW5jcnlwdGVkLW1lZGlhOyBneXJvc2NvcGU7IHBpY3R1cmUtaW4tcGljdHVyZSIgYWxsb3dmdWxsc2NyZWVuIGRhdGEtZXh0ZXJuYWw9IjEiPgoKPC9pZnJhbWU+CgojIyBJbnN0YWxsaW5nIHBhY2thZ2VzIGFuZCBoYW5kbGluZyBpbnN0YWxsYXRpb24gZXJyb3JzIChXaW5kb3dzKQoKVGhpcyB2aWRlbyBleHBsYWlucyBob3cgdG8gaW5zdGFsbCBwYWNrYWdlcyB0byBSU3R1ZGlvLCBhbmQgaG93IHRvIGhhbmRsZSBvbmUgb2YgdGhlIGNvbW1vbiBwcm9ibGVtcyB3aGVuIGluc3RhbGxpbmc6CgotICAgbm90IGJlaW5nIGFibGUgdG8gaW5zdGFsbCBwYWNrYWdlcyBiZWNhdXNlIHRoZSBkaXNjIGlzIG5vdCB3cml0ZWFibGUuCgo8aWZyYW1lIHdpZHRoPSI1NjAiIGhlaWdodD0iMzE1IiBzcmM9Imh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL2VtYmVkLy13VGNEcUpXU3pBIiBmcmFtZWJvcmRlcj0iMCIgYWxsb3c9ImFjY2VsZXJvbWV0ZXI7IGF1dG9wbGF5OyBlbmNyeXB0ZWQtbWVkaWE7IGd5cm9zY29wZTsgcGljdHVyZS1pbi1waWN0dXJlIiBhbGxvd2Z1bGxzY3JlZW4gZGF0YS1leHRlcm5hbD0iMSI+Cgo8L2lmcmFtZT4KCiMjIFByb2JsZW1zIGluc3RhbGxpbmcgcGFja2FnZXMKClVuZm9ydHVuYXRlbHksIHBlb3BsZSBzb21ldGltZXMgaGF2ZSBwcm9ibGVtcyBpbnN0YWxsaW5nIHBhY2thZ2VzIG9uIFdpbmRvd3MgMTAuIFR3byBvZiB0aGUgbWFpbiBpc3N1ZXMgYXJlOgoKMS4gIG5vdCBiZWluZyBhYmxlIHRvIGluc3RhbGwgcGFja2FnZXMgYmVjYXVzZSB0aGUgZGlzYyBpcyBub3Qgd3JpdGVhYmxlLgoKMi4gIHBhY2thZ2VzIHNhdmluZyB0byBPbmVEcml2ZSBhdXRvbWF0aWNhbGx5CgpUaGUgdmlkZW8gYWJvdmUgYnJpZWZseSBleHBsYWluZWQgaG93IHRvIGRlYWwgd2l0aCB0aGUgZmlyc3QgcHJvYmxlbSwgaW4gc3VtbWFyeToKCi0gICBxdWl0IGBSU3R1ZGlvYAoKLSAgIHJpZ2h0LWNsaWNrIG9uIGBSU3R1ZGlvYCBpY29uCgotICAgY2hvb3NlICoqUnVuIGFzIEFkbWluaXN0cmF0b3IqKiAo566h55CG6ICF44Go44GX44Gm5a6f6KGM77yJCgpUaGUgc2Vjb25kIHByb2JsZW0gaXMgYSBiaXQgbW9yZSBjb21wbGljYXRlZCwgYnV0IFt0aGlzIHBhZ2VdKGh0dHBzOi8vbWVkaXVtLmNvbS9AVmFsaWRTY2llbmNlL2hvdy10by1maXgtcnN0dWRpb3MtcGFja2FnZS1pbnN0YWxsYXRpb24tb24td2luZG93cy0xMC1jMWU2MDJiZjNhMWYpIGhhcyBkZXRhaWxlZCBpbnN0cnVjdGlvbnMgb24gZGVhbGluZyB3aXRoIGl0LgoKRm9yIG1vcmUgZGV0YWlscyBhYm91dCBoYW5kbGluZyBpbnN0YWxsYXRpb24gcHJvYmxlbXMgKGluIEphcGFuZXNlKSwgc2VlIFt0aGlzIGV4Y2VsbGVudCBibG9nIHBvc3RdKGh0dHA6Ly9yeW90YW11Z2l5YW1hLmNvbS8yMDIwLzA4LzAzL3JpbnN0YWxsLykuCgojIyBTZXR0aW5nIFVwIGEgV29ya2Zsb3cgey19CgpSU3R1ZGlvIGlzIGFuIGludGVncmF0ZWQgZGV2ZWxvcG1lbnQgZW52aXJvbm1lbnQgKGFsc28ga25vd24gYXMgYW4gSURFKSBwb3B1bGFybHkgdXNlZCBhbW9uZyBkYXRhIHNjaWVudGlzdHMgZm9yIHdyaXRpbmcgUiBjb2RlLiBJdCBpcyBhIHBvd2VyZnVsIHRvb2wgdGhhdCBjYW4gYmUgdXNlZCB0byB3cml0ZSBhbmQgZGVidWcgY29kZSwgdmlldyB2aXN1YWxpemF0aW9ucywgcHVsbCB1cCBkb2N1bWVudGF0aW9uLCB3cml0ZSAibm90ZWJvb2tzIiwgYW5kIG11Y2ggbW9yZSB3aGljaCB3ZSB3aWxsIHByb2JhYmx5IG5vdCBnZXQgdG8gc2VlISBJbiB0aGlzIHNlY3Rpb24gd2Ugd2lsbCBnbyBvdmVyIHNldHRpbmcgdXAgUlN0dWRpbyBvbiB5b3VyIG1hY2hpbmUuIAoKIyMjIFBvc2l0IENsb3VkIGFuZCBSU3R1ZGlvIHstfQoKVGhlcmUgYXJlIHR3byB3YXlzIHRvIHdvcmsgd2l0aCBSLiBUaGUgZmlyc3Qgb3B0aW9uIGlzIFBvc2l0IENsb3VkLCBhIGxpZ2h0d2VpZ2h0IGFuZCBjbG91ZC1iYXNlZCBpbnRlcmZhY2UgdG8gUlN0dWRpby4gSWYgeW91IHVzZSBQb3NpdCBDbG91ZCwgeW91IGNhbiBjb2RlIHJpZ2h0IGZyb20geW91ciBmYXZvcml0ZSBicm93c2VyISBIb3dldmVyLCBiZWNhdXNlIFBvc2l0IENsb3VkIGlzIGNsb3VkLWJhc2VkLCB0aGUgY29kZSB5b3Ugd3JpdGUgaXMgbm90IGV4ZWN1dGVkIG9uIHlvdXIgbWFjaGluZSBhbmQsIGluc3RlYWQsIHVzZXMgc29tZW9uZSBlbHNlJ3MgY29tcHV0YXRpb25hbCByZXNvdXJjZXMuIFBvc2l0IENsb3VkIG9mZmVycyBhICJmcmVlIHRpZXIiIHRoYXQgZ2l2ZXMgYWNjZXNzIHRvIGxpbWl0ZWQgcmVzb3VyY2VzICgxR0IgbWVtb3J5IGFuZCAxIENQVSBwZXIgcHJvamVjdCkgd2l0aCAyNSBwcm9qZWN0IGhvdXJzL21vbnRoLiBUaGlzIHNob3VsZCBiZSBzdWZmaWNpZW50IGZvciB0aGUgZXhhbXBsZXMgYW5kIGV4ZXJjaXNlcyBjb3ZlcmVkIGluIHRoaXMgdGV4dCwgYnV0IHlvdSBtYXkgcnVuIHVwIGFnYWluc3QgdGhlIHByb2plY3QgaG91ciBxdW90YS4gQSBwYWlkIHRpZXIgaXMgYXZhaWxhYmxlIHRoYXQgZ2l2ZXMgbW9yZSBwcm9qZWN0IGhvdXJzIGFuZCBjb21wdXRhdGlvbmFsIHBvd2VyLiBXZSByZWNvbW1lbmQgUG9zaXQgQ2xvdWQgdG8gc3R1ZGVudHMgd2l0aCBvbGRlciBtYWNoaW5lcyBhbmQgYW55b25lIHdobyBwcmVmZXJzIGEgemVyby1pbnN0YWxsYXRpb24gc2V0dXAgZm9yIGdldHRpbmcgc3RhcnRlZC4gUG9zaXQgQ2xvdWQgaXMgYXZhaWxhYmxlIGhlcmU6CgoqIFBvc2l0IENsb3VkOiBodHRwczovL3Bvc2l0LmNsb3VkLyAKClRoZSBzZWNvbmQgb3B0aW9uIGlzIHRvIGluc3RhbGwgUiBhbmQgUlN0dWRpbyBEZXNrdG9wIGRpcmVjdGx5IHRvIHlvdXIgc3lzdGVtLiBUaGV5IGNhbiBiZSBmb3VuZCBhdCB0aGUgZm9sbG93aW5nIGxpbmtzOiAKCiogUjogaHR0cHM6Ly9jbG91ZC5yLXByb2plY3Qub3JnCiogUlN0dWRpbzogaHR0cHM6Ly9wb3NpdC5jby9kb3dubG9hZC9yc3R1ZGlvLWRlc2t0b3AvI2Rvd25sb2FkCgojIyMgQ3JlYXRpbmcgYSBSU3R1ZGlvIFByb2plY3Qgey19CgpJZiB5b3UgYXJlIHdvcmtpbmcgb24gUG9zaXQgQ2xvdWQsIG5hdmlnYXRlIHRvIHlvdXIgd29ya3NwYWNlIGFuZCBjcmVhdGUgYSBuZXcgUlN0dWRpbyBwcm9qZWN0IGJ5IGNsaWNraW5nICJOZXcgUHJvamVjdCIgYW5kIHRoZW4gIk5ldyBSU3R1ZGlvIFByb2plY3QiLiBUaGlzIHNob3VsZCBicmluZyB5b3UgaW50byBhIFJTdHVkaW8gZW52aXJvbm1lbnQuIE9uY2UgdGhlcmUsIGZlZWwgZnJlZSB0byBza2lwIHRvIHRoZSBuZXh0IHNlY3Rpb24uICAKCklmIHlvdSBhcmUgd29ya2luZyB3aXRoIGEgbG9jYWwgaW5zdGFsbGF0aW9uLCBsYXVuY2ggdGhlIFJTdHVkaW8gYXBwbGljYXRpb24uIFRoZXJlIG1heSBiZSBzb21lICJnZXR0aW5nIHN0YXJ0ZWQiIGhlbHAgZ3VpZGVzIHRoYXQgeW91IGFyZSBwcmVzZW50ZWQgd2l0aCwgd2hpY2ggeW91IGNhbiBpZ25vcmUgZm9yIG5vdy4gWW91ciBuZXh0IHN0ZXAgd2lsbCBiZSB0byBjcmVhdGUgYSBfX1IgcHJvamVjdF9fIGJ5IGdvaW5nIHRvOiBgRmlsZSA+IE5ldyBQcm9qZWN0Li4uYC4gCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSJjZW50ZXIiLCBvdXQud2lkdGg9JzYwJScsIGZpZy5hc3A9MS8yfQpsaWJyYXJ5KGhlcmUpCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmUoImltYWdlcyIsICJwcm9qZWN0X3dpemFyZC5wbmciKSkKYGBgCgpGcm9tIHRoZSBvcHRpb25zIHRoYXQgYXJlIHByZXNlbnRlZCwgc2VsZWN0IGBOZXcgRGlyZWN0b3J5ID4gTmV3IFByb2plY3RgLiBUaGlzIHNob3VsZCBicmluZyB1cCB0aGUgZm9sbG93aW5nIHNjcmVlbi4gCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSJjZW50ZXIiLCBvdXQud2lkdGg9JzYwJScsIGZpZy5hc3A9MS8yfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlKCJpbWFnZXMiLCAicHJvamVjdF93aXphcmQyLnBuZyIpKQpgYGAKCkluIHRoZSBpbnB1dCBib3ggdGhhdCBhc2tzIGZvciBhICJEaXJlY3RvcnkgbmFtZSIsIHlvdSBjYW4gbmFtZSBpdCBob3dldmVyIHlvdSBsaWtlLiBGb3IgaW5zdGFuY2UsIHdlIG5hbWVkIG91cnMgIkNTQzEwMCIuIFRoZSBkZWZhdWx0IGRpcmVjdG9yeSBmb3IgdGhpcyBwcm9qZWN0IGlzIGZpbmUsIGJ1dCBkbyBtYWtlIGEgbm90ZSBvZiBpdDsgYWxzbywgZG8gbm90IHdvcnJ5IGFib3V0IGFueSBvZiB0aGUgY2hlY2sgYm94ZXMgYW5kIGxlYXZlIHRob3NlIHVuY2hlY2tlZC4gCgpXaGVuIHlvdSBhcmUgcmVhZHksIGdvIGFoZWFkIGFuZCBzZWxlY3QgYENyZWF0ZSBQcm9qZWN0YC4gCgojIyMgTWVldCBSU3R1ZGlvIHstfQoKWW91IHNob3VsZCBub3cgYmUgcHJlc2VudGVkIHdpdGggYSB2aWV3IHRoYXQgbG9va3MgbGlrZSB0aGUgZm9sbG93aW5nOiAKCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuYWxpZ249ImNlbnRlciIsIG91dC53aWR0aD0nODAlJywgZmlnLmFzcD0xLzJ9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKGhlcmUoJ2ltYWdlcycsJ3JzdHVkaW9fZW52aXJvbm1lbnQucG5nJykpCmBgYAoKTGV0IHVzIGdvIG92ZXIgZWFjaCBvZiB0aGUgbGFiZWxlZCBwYXJ0cy4gCgoqIF9fQ29uc29sZS5fXyBUaGlzIGlzIGEgZ3JlYXQgcGxhY2UgdG8gZ2V0IHN0YXJ0ZWQgY29kaW5nIGluIFIhIEl0IGlzbid0IGZ1bGx5IGZlYXR1cmVkIGxpa2UgYSBSIG1hcmtkb3duIG5vdGVib29rIGlzICh3aGljaCB3ZSB3aWxsIHNlZSBpbiBhIG1vbWVudCkgYW5kIHlvdSB3b3VsZG4ndCB3YW50IHRvIHB1dCBhbnl0aGluZyBpbXBvcnRhbnQgaGVyZSBhcyBpdCB3aWxsIGJlIGxvc3QgYXMgc29vbiBhcyB5b3UgZXhpdCBSU3R1ZGlvLiBIb3dldmVyLCBpdCBjYW4gYmUgdXNlZnVsIGZvciBjaGVja2luZyBzbWFsbCB0aGluZ3MsIGUuZy4gYXMgYSBidWlsdC1pbiBjYWxjdWxhdG9yLiBUcnkgb3V0IGAyICsgMmAgYW5kIHNlZSB3aGF0IHlvdSBnZXQhIFlvdSBjYW4gYWxzbyBjaGVjayB0aGUgY3VycmVudCAid29ya2luZyBkaXJlY3RvcnkiIGJ5IHR5cGluZyBgZ2V0d2QoKWAuIFRoaXMgd2lsbCBwdWxsIHVwIHRoZSBkaXJlY3RvcnkvZm9sZGVyIG9uIHlvdXIgbWFjaGluZSB3aGVyZSB5b3UgY3JlYXRlZCB0aGlzIHByb2plY3QuICAKCiogX19FbnZpcm9ubWVudC5fXyBUaGlzIGlzIHdoZXJlIFJTdHVkaW8ga2VlcHMgdHJhY2sgb2YgIm9iamVjdHMiIHRoYXQgUiBoYXMgY3JlYXRlZCBkdXJpbmcgeW91ciBzZXNzaW9uLiBXZSBoYXZlbid0IGxlYXJuZWQgd2hhdCB0aGVzZSBhcmUgeWV0LCBidXQgeW91IGNhbiByZXZpc2l0IHRoaXMgcGFydCBvZiB0aGUgbm90ZXMgYWdhaW4gdG8gbWFrZSBzZW5zZSBvZiB3aGF0IGlzIGdvaW5nIG9uIGhlcmUuIApUbyBkZW1vbnN0cmF0ZSB0aGlzLCBsZXQgdXMgY3JlYXRlIGFuIG9iamVjdCBgbXlfdmFsdWVgIHRoYXQgaG9sZHMgdGhlIHZhbHVlIDUuIFRoZSBiZW5lZml0IG9mIHRoZSBlbnZpcm9ubWVudCB2aWV3IGlzIHRoYXQgaXQgcmVtaW5kcyB1cyBvZiB0aGUgY3VycmVudCB2YWx1ZSBoZWxkIGJ5IHRoZSBvYmplY3QuIFJ1biB0aGlzIGNlbGwgaW4gdGhlICJDb25zb2xlIiBhcmVhIG9mIFJTdHVkaW8gYW5kIHRoZW4gZ2xhbmNlIG92ZXIgYXQgdGhlICJFbnZpcm9ubWVudCIgdmlldy4gICAKCmBgYHtyfQpteV92YWx1ZSA8LSA1CmBgYAoKTm90ZSB3aGF0IGhhcHBlbnMgaW4gdGhlIGVudmlyb25tZW50IHZpZXcgaWYgd2Ugd2VyZSB0byBjaGFuZ2UgdGhlIHZhbHVlLiBBcyBiZWZvcmUsIGNvcHkgdGhlIGZvbGxvd2luZyBsaW5lIG9mIGNvZGUgaW50byB5b3VyIGNvbnNvbGUuIAoKYGBge3J9Cm15X3ZhbHVlIDwtICJoZWxsbyBkYXRhIHNjaWVuY2UhIgpgYGAKCiogX19GaWxlIEV4cGxvcmVyL1Bsb3RzL0hlbHAuX18gVGhpcyBhcmVhIGlzIGFjdHVhbGx5IGEgInRocmVlLWluLW9uZSIuIEF0IHRoZSBtb21lbnQsIGl0IHByZXNlbnRzIHlvdSB0aGUgZmlsZXMgYW5kIGZvbGRlcnMgdGhhdCBjdXJyZW50bHkgZXhpc3QgaW5zaWRlIHlvdXIgcHJvamVjdCAtLSB3aGljaCBpcyBwcmFjdGljYWxseSBub3RoaW5nIGF0IHRoZSBtb21lbnQuIFdlIHdpbGwgY3JlYXRlIHNvbWUgZGlyZWN0b3JpZXMgaW4ganVzdCBhIG1vbWVudC4gCgpUaGUgX19wbG90cyB2aWV3X18gcmV2ZWFscyBpdHNlbGYgd2hlbiB5b3UgaGF2ZSBjcmVhdGVkIGEgdmlzdWFsaXphdGlvbiBvbiB0aGUgY29uc29sZS4gSGVyZSBpcyBhbiBleGFtcGxlLiBZb3UgbmVlZCBub3QgdW5kZXJzdGFuZCB3aGF0IHRoaXMgY29kZSBkb2VzOyBzaW1wbHkgY29weSBhbmQgcGFzdGUgaW50byB0aGUgY29uc29sZSwgYW5kIHJ1bi4gCgpgYGB7ciBldmFsID0gRkFMU0V9CnBsb3QoY3lsIH4gbXBnLCBtdGNhcnMpCmBgYAoKTGV0IHVzIG5hdmlnYXRlIHRvIHRoZSBfX2hlbHAgdGFiX18sIHdoaWNoIHNob3VsZCBiZSBvbmUgb3IgdHdvIHRhYnMgZG93biBmcm9tIHRoZSAiUGxvdHMiIHRhYi4gSGVyZSwgd2UgY2FuIGxvb2sgdXAgZG9jdW1lbnRhdGlvbiBhYm91dCBmdW5jdGlvbnMgb3IgZGF0YXNldHMgd2Ugd291bGQgbGlrZSB0byBsZWFybiBtb3JlIGFib3V0LiBGb3IgaW5zdGFuY2UsIGluIHRoZSBzZWFyY2ggYmFyLCB3ZSBjYW4gdHlwZSBgcGxvdGAgdG8gbG9vayB1cCBpbmZvcm1hdGlvbiBmb3IgdGhlIGZ1bmN0aW9uIGBwbG90YCB3ZSBqdXN0IHVzZWQgZWFybGllci4gCgpBbiBlcXVpdmFsZW50LCBhbmQgcGVyaGFwcyBtb3JlIHN0cmFpZ2h0Zm9yd2FyZCwgd2F5IG9mIGxvb2tpbmcgdXAgZG9jdW1lbnRhdGlvbiBpcyByaWdodCBmcm9tIHRoZSBjb25zb2xlLiBKdXN0IHR5cGUgaW4gYD9wbG90YCwgYW5kIGhpdCBlbnRlci4gIAoKIyMjIE9yZ2FuaXppbmcgeW91ciB3b3JrIHstfQoKV2UgY2FuIGNyZWF0ZSBmb2xkZXJzIGluIG91ciBwcm9qZWN0IHRvIGJldHRlciBvcmdhbml6ZSBvdXIgd29yay4gV2UgcmVjb21tZW5kIHRoZSBmb2xsb3dpbmcgc3RydWN0dXJlLiBZb3UgY2FuIHVzZSB0aGUgYE5ldyBGb2xkZXJgIGJ1dHRvbiBpbiB0aGUgZmlsZSBleHBsb3JlciB2aWV3IHRvIGNyZWF0ZSB0aGVzZSBkaXJlY3Rvcmllcy4gCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmFsaWduPSJjZW50ZXIiLCBvdXQud2lkdGg9JzYwJScsIGZpZy5hc3A9MS8yfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcyhoZXJlKCdpbWFnZXMnLCdmaWxlX2RpcmVjdG9yeS5wbmcnKSkKYGBgCgpUaGlzIGZvbGRlciBzdHJ1Y3R1cmUgY2FuIGJlIHVzZWZ1bCBpZiB5b3UgYXJlIHRha2luZyBhIGNvdXJzZSB0aGF0IHJlcXVpcmVzIHVzaW5nIFJTdHVkaW8uIFRoZSBmb2xkZXIgbmFtZXMgc2hvdWxkIGJlIHNlbGYtZXhwbGFuYXRvcnksIGJ1dCBoZXJlIGlzIGEgYnJpZWYgZXhwbGFuYXRpb246IAoKKiBgbGFic2AsIGZvciB3b3JraW5nIG9uIGxhYiBhc3NpZ25tZW50cy4gCiogYGh3YCwgZm9yIHdvcmtpbmcgb24gaG9tZXdvcmsgYXNzaWdubWVudHMuCiogYG5vdGVzYCwgZm9yIHlvdXIgb3duIG5vdGVzLiAKKiBgcHJvamVjdGAsIGZvciB3b3JraW5nIG9uIHByb2plY3RzLiAgCgojIyMgUiBtYXJrZG93biBub3RlYm9va3Mgey19CgpSIG1hcmtkb3duIG5vdGVib29rcyBhbGxvdyB1c2VycyB0byBpbnRlcnNwZXJzZSBjb2RlIHdpdGggcHJvc2UgaW4gYW4gaW50dWl0aXZlIG1hbm5lci4gVGhpcyBpcyBncmVhdCB0byB1c2UgaW4gcHJhY3RpY2UgZm9yIHNoYXJpbmcgYW5kIGNvbW11bmljYXRpbmcgeW91ciB3b3JrIHRvIHBlZXJzLgoKV2UgY2FuIHRyeSBwbGF5aW5nIHdpdGggYW4gZXhhbXBsZSBub3RlYm9vayB0aGF0IFJTdHVkaW8gYXV0b21hdGljYWxseSBnZW5lcmF0ZXMgd2hlbiBjcmVhdGluZyBhIG5vdGVib29rLiBMZXQgdXMgdHJ5IGl0LiAKCk5hdmlnYXRlIHRvIGBGaWxlID4gTmV3IEZpbGUgPiBSIE5vdGVib29rYC4gU2F2ZSB0aGlzIG5vdGVib29rIHNvbWV3aGVyZSBhcHByb3ByaWF0ZSwgc2F5LCBpbiB5b3VyIGBub3Rlc2AgZGlyZWN0b3J5LiBIZXJlIGlzIHdoYXQgeW91IHNob3VsZCBiZSBzZWVpbmc6IAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5hbGlnbj0iY2VudGVyIiwgb3V0LndpZHRoPSc2MCUnLCBmaWcuYXNwPTEvMn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoaGVyZSgnaW1hZ2VzJywnbm90ZWJvb2tfZXhhbXBsZS5wbmcnKSkKYGBgCgpMZXQgdXMgZ28gb3ZlciB0aGUgcGFydHMuICAKCiogX19NYXJrZG93bi5fXyBIZXJlIHlvdSBjYW4gdHlwZSB0ZXh0IGFzIHlvdSB3b3VsZCBub3JtYWxseSBpbiB0ZXh0IHByb2Nlc3Npbmcgc29mdHdhcmUgbGlrZSBOb3RlcGFkKyssIFRleHRFZGl0LCBvciBXb3JkLiBUaGUgY29vbCBmZWF0dXJlIGlzIHRoYXQgdGhlIHRleHQgY2FuIGJlIG1hcmtlZCB1cCB1c2luZyBhIGxhbmd1YWdlIGNhbGxlZCAqbWFya2Rvd24qLiBbSGVyZSBpcyBhIGNoZWF0IHNoZWV0XShodHRwczovL2dpdGh1Yi5jb20vYWRhbS1wL21hcmtkb3duLWhlcmUvd2lraS9NYXJrZG93bi1DaGVhdHNoZWV0KSB0aGF0IHlvdSBjYW4gdXNlIGFzIHJlZmVyZW5jZS4KCiogX19Db2RlX18uIEhlcmUgaXMgd2hlcmUgd2Ugd2lsbCBiZSB3cml0aW5nIG1vc3Qgb2Ygb3VyIFIgY29kZS4gV2UgbWF5IGFsc28gY2FsbCB0aGVzZSBjb2RlICJjZWxscyIgb3IgImJsb2NrcyIuIFdoZW4geW91IGFyZSByZWFkeSB0byBydW4gYSBjb2RlIGJsb2NrLCB5b3UgY2FuIHByZXNzIHRoZSBncmVlbiAicGxheSIgYnV0dG9uIHRoYXQgYXBwZWFycyB0b3dhcmQgdGhlIHRvcCByaWdodCBvZiB0aGUgYmxvY2suIE9ic2VydmUgaG93IGl0IHByb2R1Y2VzIG91dHB1dCBpbi1saW5lIGp1c3QgYmVsb3cgdGhlIGNvZGUgLS0gbmVhdCwgcmlnaHQ/ICAgICAKCiogX19PcHRpb24gUGFuZV9fLiBUaGVyZSBhcmUgc29tZSBmZWF0dXJlcyBoZXJlIHlvdSBtYXkgd2lzaCB0byBleHBsb3JlIGxpa2UgdGhlIGBSdW5gIGJ1dHRvbiB3aGljaCBhbGxvd3MgeW91IHRvIHJ1biBhbGwgdGhlIGNvZGUgYmxvY2tzIGluIGEgbm90ZWJvb2sgYXQgb25jZSwgZXRjLiBUaGUgZmVhdHVyZSB3ZSB3b3VsZCBsaWtlIHRvIGRyYXcgeW91ciBhdHRlbnRpb24gdG8gaXMgc29tZXRoaW5nIGNhbGxlZCAqa25pdHRpbmcqLCB3aGljaCBjYW4gYmUgZm91bmQgYWZ0ZXIgcHJlc3NpbmcgdGhlIGRvd253YXJkIGFycm93IG5leHQgdG8gYFByZXZpZXdgLiBUaGlzIHNob3VsZCBzaG93IHNldmVyYWwgb3B0aW9ucywgb25lIG9mIHdoaWNoIGlzIGBLbml0IHRvIFBERmAuIEdvIGFoZWFkIGFuZCBzZWxlY3QgaXQuIAoKSWYgeW91IG5hdmlnYXRlIHRvIHRoZSBgbm90ZXNgIGRpcmVjdG9yeSBpbiB0aGUgRmlsZSBFeHBsb3JlciAob3Igd2hlcmV2ZXIgeW91IGNyZWF0ZWQgdGhpcyBub3RlYm9vayksIHlvdSBzaG91bGQgc2VlIGEgUERGIGZpbGUgdGhhdCBoYXMgYmVlbiBnZW5lcmF0ZWQuIENsaWNraW5nIG9uIGl0IGluIHRoZSBGaWxlIEV4cGxvcmVyIHNob3VsZCBwcmVzZW50IHlvdSB3aXRoIGEgUERGIHZlcnNpb24gb2YgdGhlIG5vdGVib29rLiAKCldoYXQgUlN0dWRpbyBkaWQgd2FzIHRha2Ugb3VyIFIgbWFya2Rvd24gZmlsZSBhbmQgY29udmVydCBpdCB0byBhIFBERiB1c2luZyBbTGFUZVhdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0xhVGVYKS4gQmVuZWF0aCBlYWNoIGNvZGUgYmxvY2sgaXMgdGhlIGNvcnJlc3BvbmRpbmcgb3V0cHV0LCBpbnRlcnNwZXJzZWQgbmVhdGx5IHdpdGggdGhlIHN1cnJvdW5kaW5nIHByb3NlIC0tIGFsbCBmb3JtYXR0aW5nIHRha2VuIGNhcmUgb2YgZm9yIHlvdSA6LSkKCiMjIyBQcmVmZXJlbmNlcyBzZXR0aW5ncyB7LX0KCkJlZm9yZSB3ZSBlbmQgdGhpcyB0dXRvcmlhbCwgd2UgYWxzbyBuZWVkIHRvIHNldCB0d28gUlN0dWRpbyBzZXR0aW5ncy4gVGhpcyB3aWxsIGhlbHAgdG8gYXZvaWQgYW55IGhlYXJ0YWNoZSB3aGVuIHdvcmtpbmcgdGhyb3VnaCB0aGlzIHRleHQuIAoKT3BlbiB1cCBgUHJlZmVyZW5jZXNgIGluIFJTdHVkaW8uIERvIHRoZSBmb2xsb3dpbmcgaW4gdGhlIGBHZW5lcmFsYCB0YWI6CgoqIFVuY2hlY2sgdGhlIGJveCB0aGF0IHNheXMgIlJlc3RvcmUgLlJEYXRhIGludG8gd29ya3NwYWNlIGF0IHN0YXJ0dXAiCiogRm9sbG93aW5nIHRoZSB0ZXh0IHRoYXQgc2F5cyAiU2F2ZSB3b3Jrc3BhY2UgZGF0YSB0byAuUkRhdGEgb24gZXhpdDoiLCBzZWxlY3QgYE5ldmVyYC4gCgpUaGlzIGNvbXBsZXRlcyB0aGUgc2V0dXAhIAoKIyMgRXhlcmNpc2VzIHstfQoKQmUgc3VyZSB0byBpbnN0YWxsIGFuZCBsb2FkIHRoZSBmb2xsb3dpbmcgcGFja2FnZXMgaW50byB5b3VyIFIgZW52aXJvbm1lbnQgYmVmb3JlIGJlZ2lubmluZyB0aGlzIGV4ZXJjaXNlIHNldC4KCmBgYHtyIGV2YWw9RkFMU0V9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGVkc2RhdGEpCmxpYnJhcnkoZ2FwbWluZGVyKQpsaWJyYXJ5KGVtb2ppZm9udCkKYGBgCgoqKlF1ZXN0aW9uIDEqKiBUaGUgZ29hbCBvZiB0aGlzIHF1ZXN0aW9uIGlzIHRvIGRldmVsb3AgZmFtaWxpYXJpdHkgd2l0aCBSLCBSU3R1ZGlvLCBhbmQgaW5zdGFsbGluZy9sb2FkaW5nIHBhY2thZ2VzIGludG8gYSBSU3R1ZGlvIGVudmlyb25tZW50LiBBbGwgd29yayBmb3IgdGhpcyBxdWVzdGlvbiBjYW4gYmUgZG9uZSB1c2luZyB0aGUgQ29uc29sZSB3aW5kb3cgaW5zaWRlIFJTdHVkaW8gb3IsIHByZWZlcmFibHksIGJ5IGNyZWF0aW5nIGNvZGUgY2h1bmtzIGluc2lkZSBhIFIgbWFya2Rvd24gbm90ZWJvb2sgKHNlZSBTZWN0aW9uIDEuNCkuICAKCiogKipRdWVzdGlvbiAxLjEqKiBJbnN0YWxsIHRoZSBwYWNrYWdlcyBgdGlkeXZlcnNlYCwgYGVtb2ppZm9udGAsIGBkZXZ0b29sc2AsIGFuZCBgZWRzZGF0YWAgb24geW91ciBzeXN0ZW0uIFJlY2FsbCB0aGF0IHRoZSBgZWRzZGF0YWAgcGFja2FnZSBpcyBub3QgYXZhaWxhYmxlIG9uIENSQU4gYW5kIG11c3QgYmUgaW5zdGFsbGVkIHVzaW5nIGBpbnN0YWxsX2dpdGh1YmAgZnJvbSB0aGUgYGRldnRvb2xzYCBwYWNrYWdlLiBUaGVuIGxvYWQgdGhlc2UgcGFja2FnZXMgaW50byB5b3VyIGVudmlyb25tZW50LiAgCgoqICoqUXVlc3Rpb24gMS4yKiogYGVtb2ppKClgIGlzIGEgKmZ1bmN0aW9uKiBmcm9tIHRoZSBwYWNrYWdlIGBlbW9qaWZvbnRgIHdoaWNoIGNvbnZlcnRzIGFuIGVtb2ppIGFsaWFzIHRvIGl0cyAidW5pY29kZSIgcmVwcmVzZW50YXRpb24uIFRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbiBnaXZlcyBhbiBleGFtcGxlLiBUeXBlIGFuZCBydW4gdGhlIGZvbGxvd2luZyBjb2RlIGNodW5rOiAKCiAgYGBge3IgZXZhbD1GQUxTRX0KICBlbW9qaSgic3RhciIpCiAgYGBgCgogIFRyeSBjb252ZXJ0aW5nIGFub3RoZXIgZW1vamkgYWxpYXMgbmFtZSB0byBpdHMgInVuaWNvZGUiIHJlcHJlc2VudGF0aW9uLgoKKiAqKlF1ZXN0aW9uIDEuMyoqIFRoZXJlIGFyZSBhY3R1YWxseSBhIGxvdCBvZiBlbW9qaXMgd2l0aCBzdGFycy4gVXNlIHRoZSBmdW5jdGlvbiBgc2VhcmNoX2Vtb2ppKClgIHRvIGZpbmQgYWxsIGFsaWFzZXMgZm9yICJzdGFyIi4gSG93IG1hbnkgYXJlIHRoZXJlPyBfX0hpbnQ6X18gdXNlIGA/c2VhcmNoX2Vtb2ppYCB0byBwdWxsIHVwIHRoZSBoZWxwIGRvY3VtZW50YXRpb24gZm9yIHRoaXMgZnVuY3Rpb24uIFRoYXQgaXMgYWx3YXlzIGEgZ29vZCBpZGVhIHdoZW4geW91IGFyZSBpbiBkb3VidCBvZiBob3cgdG8gdXNlIGEgZnVuY3Rpb24uICAKCiogKipRdWVzdGlvbiAxLjQqKiAgV2UgaGF2ZSBtYWRlIGEgY29kaW5nIGJsdW5kZXIgaW4gdGhlIG5leHQgY2h1bmsuIFR5cGUgdGhlIGZvbGxvd2luZyBhbmQgcnVuIHRoaXMgY29kZSBjaHVuayB0byBzZWUgd2hhdCBoYXBwZW5zLiBUaGVuIGZpeCB0aGUgY29kZSBzbyB0aGF0IHlvdSBjYW4gcnVuIHRoZSBjaHVuayB3aXRob3V0IGVycm9yIGFuZCBzZWUgdGhlIGludGVuZGVkIG1lc3NhZ2UuCgogIGBgYHtyIGV2YWw9RkFMU0V9CiAgcHJpbnQoIndoYXQgaXMgbWlzc2luZz8KICBgYGAKCiogKipRdWVzdGlvbiAxLjUqKiBXaGF0IGhhcHBlbnMgaWYgd2UgdHJ5IGBwcmludGBpbmcgYSBuYW1lIHRoYXQgaGFzIG5vdCBiZWVuIGFzc2lnbmVkIGFueXRoaW5nPyBUcnkgdG8gZGlzcGxheSB0aGUgdmFsdWUgZm9yIHRoZSBuYW1lIGBidWJibGVgIG9yIGB0ZWFgLiBXaGF0IG1lc3NhZ2UgaXMgcHJvZHVjZWQ/IEFyZSB5b3Ugc3VycHJpc2VkPyAKCiAgYGBge3IgZXZhbD1GQUxTRX0KICBidWJibGUKICB0ZWEKICBgYGAKCgoqKlF1ZXN0aW9uIDIqKiBXZSBzYXcgaW4gdGhlIHRleHRib29rIHRoYXQgd2UgY2FuIHZpc3VhbGl6ZSB3b3JkIHJlbGF0aW9uc2hpcHMgaW4gTW9ieSBEaWNrIHVzaW5nIGB0aWR5dmVyc2VgIGFuZCB0aGUgUiBwcm9ncmFtbWluZyBsYW5ndWFnZS4gSW4gdGhpcyBwYXJ0IHdlIHdpbGwgY29udGludWUgZXhwbG9yaW5nIHRoZXNlIHJlbGF0aW9uc2hpcHMgYW5kIGFuc3dlciBzb21lIHF1ZXN0aW9ucyBhYm91dCB3aGF0IGlzIGJlaW5nIHJlcHJlc2VudGVkLiBCZSBzdXJlIHlvdSBoYXZlIGFsc28gcmVhZCBTZWN0aW9uIDEuMyBvZiB0aGUgdGV4dGJvb2suIAoKUnVuIHRoZSBmb2xsb3dpbmcgY2h1bmsgdG8gcHJvZHVjZSB0aGUgdmlzdWFsaXphdGlvbiB3ZSB3aWxsIGV4YW1pbmUgZm9yIHRoaXMgcXVlc3Rpb24uIFlvdSBkbyBfX05PVF9fIG5lZWQgdG8gdW5kZXJzdGFuZCB3aGF0IGlzIGhhcHBlbmluZyBpbiB0aGUgZm9sbG93aW5nIGNvZGUhCgpgYGB7ciBldmFsPUZBTFNFfQpsaWJyYXJ5KGVkc2RhdGEpCmdncGxvdChtb2J5X2RpY2tfY291bnRzKSArIAogIGdlb21fcG9pbnQoYWVzKHggPSB3aGFsZSwgeSA9IHNlYSwgY29sb3IgPSAic2VhIikpICsgCiAgZ2VvbV9wb2ludChhZXMoeCA9IHdoYWxlLCB5ID0gYWhhYiwgY29sb3IgPSAiYWhhYiIpKSArIAogIHlsYWIoImNvdW50IikKYGBgCgoqICoqUXVlc3Rpb24gMi4xKiogV2hhdCBpcyBiZWluZyByZXByZXNlbnRlZCBieSB0aGlzIHZpc3VhbGl6YXRpb24/IFdoYXQgaXMgc2hvd24gb24gdGhlIHgtYXhpcz8gT24gdGhlIHktYXhpcz8gUGxlYXNlIGV4cGxhaW4geW91ciBhbnN3ZXIuIAoKKiAqKlF1ZXN0aW9uIDIuMioqIEFib3V0IGhvdyBtYW55IHRpbWVzIGRpZCB0aGUgd29yZCAid2hhbGUiIG9jY3VyIGluIHRoZSBjaGFwdGVyIHRoYXQgY29udGFpbmVkIHRoZSBtb3N0IG51bWJlciBvZiBvY2N1cnJlbmNlcyBvZiB0aGUgd29yZCAiYWhhYiI/IEFzc2lnbiBlaXRoZXIgMSwgMiwgMywgNCwgb3IgNSB0byB0aGUgbmFtZSBgbW9ieV9xMmAgYmVsb3cuCgp8ICAgICAgIDEuIDIwCnwgICAgICAgMi4gMzAgCnwgICAgICAgMy4gMzUKfCAgICAgICA0LiA1NQp8ICAgICAgIDUuIDYwIAoKKiAqKlF1ZXN0aW9uIDIuMyoqIEl0IHNlZW1zIHRoYXQgdGhlIG9jY3VycmVuY2VzIG9mICJ3aGFsZSIgYXJlIG5vdCBhcyBjbG9zZWx5IGFzc29jaWF0ZWQgd2l0aCAiYWhhYiIgYXMgaXQgaXMgd2l0aCAic2VhIi4gSXMgdGhpcyBhIGZhaXIgb2JzZXJ2YXRpb24/IEV4cGxhaW4gd2h5IG9yIHdoeSBub3QuCgoKKipRdWVzdGlvbiAzKiogQWNjb3JkaW5nIHRvIHRoZSB0ZXh0Ym9vaywgd2hpY2ggb2YgdGhlIGZvbGxvd2luZywgaWYgYW55LCBhcmUgZGF0YSBzY2llbmNlIHRhc2tzPyBFeHBsYWluIHdoeSBvciB3aHkgbm90LgoKKiBBbiBpbnRlcm4gZXhhbWluZXMgcGVyZm9ybWFuY2UgYXQgYSBjb21wYW55IGJ5IGNvbXB1dGluZyBtZWFuIGFuZCBtZWRpYW4gcXVhcnRlcmx5IGVhcm5pbmdzIHVzaW5nIHNwcmVhZHNoZWV0IHNvZnR3YXJlIChlLmcuLCBNaWNyb3NvZnQgRXhjZWwsIE51bWJlcnMsIGV0YykuCiogQSBsZWFybmluZyBtYW5hZ2VtZW50IHN5c3RlbSAoTE1TKSBjb2xsZWN0cyBsYXJnZSB2b2x1bWVzIG9mIGRhdGEgb24gdXNlciBhY3Rpdml0eSBwYXR0ZXJucywgbW9kdWxlIGludGVyYWN0aW9ucywgYW5kIGRpYWdub3N0aWNzLgoqIEEgcmVzZWFyY2ggY29ob3J0IGV4cGxvcmVzIGlzc3VlcyBvZiBhdXRob3JzaGlwIGluIGEgY29sbGVjdGlvbiBvZiBjbGFzc2ljIEVuZ2xpc2ggd29ya3MgYnkgdXNpbmcgdmFyaW91cyB0ZXh0IGFuYWx5c2lzIHRvb2xzIChlLmcuLCBmcmVxdWVuY3kgYW5hbHlzaXMsIHNlbnRpbWVudCBhbmFseXNpcywgZXRjKS4KKiBBIGNvbGxlYWd1ZSByZXBvcnRzIHJlc3VsdHMgZnJvbSBhIHN0YXRpc3RpY2FsIGFuYWx5c2lzIG9uIGFuIEFsemhlaW1lcidzIGRpc2Vhc2Ugc3R1ZHkgdXNpbmcgbGluZSBjaGFydHMsICJib3gtYW5kLXdoaXNrZXIiIHBsb3RzLCBhbmQgaGlzdG9ncmFtcy4KCgoqKlF1ZXN0aW9uIDQqKiBUaGUgdGV4dGJvb2sgbGlzdHMgc29tZSBleGFtcGxlcyBvZiB3aGF0IHdvcmsgaW4gZGF0YSBzY2llbmNlIGxvb2tzIGxpa2UuIENhbiB5b3UgY29tZSB1cCB3aXRoIHR3byBvciB0aHJlZSBhZGRpdGlvbmFsIGV4YW1wbGVzIG9mIGRhdGEgc2NpZW5jZT8gV2h5IGRvIHlvdXIgZXhhbXBsZXMgZmFsbCB3aXRoaW4gdGhlIGJvdW5kYXJpZXMgb2YgImRhdGEgc2NpZW5jZSIsIGFzIGRlZmluZWQgYnkgdGhlIHRleHRib29rPyAKCgoqKlF1ZXN0aW9uIDUqKiBGb2xsb3dpbmcgYXJlIHN0ZXBzIGluIGEgZGF0YSBzY2llbmNlIHdvcmtmbG93IHRoYXQgYXJlIG91dC1vZi1vcmRlci4KCnwgICAxLiBjb2xsZWN0aW5nIGRhdGEKfCAgIDIuIGNvbW11bmljYXRpbmcgdGhlIHJlc3VsdHMgdG8gdGhlIG1hbmFnZW1lbnQKfCAgIDMuIGFzc2VtYmxpbmcgdGhlIHJlc3VsdHMgaW50byBhIHJlcG9ydAp8ICAgNC4gdHJhbnNmb3JtaW5nIHRoZSBkYXRhIHRvIGRldGVybWluZSB0aGUgbWV0aG9kIGZvciBhbmFseXNpcwp8ICAgNS4gZGV0ZXJtaW5pbmcgdGhlIGRhdGEgc291cmNlcwp8ICAgNi4gInRpZHlpbmciIHRoZSBkYXRhLCBpbmNsdWRpbmcgZmlsbGluZyBpbiBtaXNzaW5nIHZhbHVlcwp8ICAgNy4gcGVyZm9ybWluZyB0aGUgYW5hbHlzaXMgIAoKKiAqKlF1ZXN0aW9uIDUuMSoqIFB1dCB0aGUgYWJvdmUgc3RlcHMgaW4gdGhlIGNvcnJlY3Qgb3JkZXIuCgoqICoqUXVlc3Rpb24gNS4yKiogRGF0YSBzY2llbmNlIHdvcmsgaXMgb2Z0ZW4gYW4gaXRlcmF0aXZlIGFuZCBjeWNsaWNhbCBwcm9jZXNzIHRoYXQgcmVwZWF0cyB1bnRpbCBlbm91Z2ggaW5zaWdodCBjYW4gYmUgZ2xlYW5lZCBmcm9tIHRoZSBkYXRhLiBGcm9tIHRoZSB3b3JrZmxvdyBvdXRsaW5lZCBpbiAqKlF1ZXN0aW9uIDUuMSoqLCBleHBsYWluIHdoaWNoIG9mIHRoZSBzdGVwcyBtYXkgYmUgcmVwZWF0ZWQgbXVsdGlwbGUgdGltZXMuCgoK